J'ai un WebView
qui charge une page depuis l'Internet. Je veux montrer une ProgressBar
jusqu'à ce que le chargement soit terminé.
Comment puis-je écouter l'achèvement du chargement de la page d'une WebView
?
J'ai un WebView
qui charge une page depuis l'Internet. Je veux montrer une ProgressBar
jusqu'à ce que le chargement soit terminé.
Comment puis-je écouter l'achèvement du chargement de la page d'une WebView
?
Étendre le site WebViewClient et appeler onPageFinished () comme suit :
mWebView.setWebViewClient(new WebViewClient() {
public void onPageFinished(WebView view, String url) {
// do your stuff here
}
});
J'ai quelques problèmes avec les chargements externes lorsque l'Internet n'est pas très rapide. Par exemple Google Analytics ou d'autres choses de ce genre. J'ai essayé quelques solutions de contournement et cela s'est beaucoup amélioré, mais ce n'est pas encore parfait. Parfois, l'application se fige sur l'écran de chargement et il est impossible de la quitter, à moins de déconnecter le réseau ou de se connecter à un autre bon réseau. Je ne sais pas encore comment résoudre ce problème, mais j'essaie.
@Felipe pourquoi n'utilisez-vous pas quelque chose comme ça : stackoverflow.com/questions/4302912/Android-webview-timeout
Cela fonctionne parfaitement. Vous pouvez utiliser mWebView.setVisibility(View.INVISIBLE) avant le chargement. Une fois le chargement terminé, vous pouvez le remettre à View.VISIBLE. Je l'ai utilisé avec ce splash screen : Android-developers.blogspot.de/2009/03/
@ian ce n'est pas précis à 100%. Si vous avez plusieurs iframes dans une page, vous aurez plusieurs onPageFinished (et onPageStarted). Et si vous avez plusieurs redirections, cela peut aussi échouer. Cette approche résout (presque) tous les problèmes :
boolean loadingFinished = true;
boolean redirect = false;
mWebView.setWebViewClient(new WebViewClient() {
@Override
public boolean shouldOverrideUrlLoading(WebView view, String urlNewString) {
if (!loadingFinished) {
redirect = true;
}
loadingFinished = false;
webView.loadUrl(urlNewString);
return true;
}
@Override
public void onPageStarted(WebView view, String url) {
loadingFinished = false;
//SHOW LOADING IF IT ISNT ALREADY VISIBLE
}
@Override
public void onPageFinished(WebView view, String url) {
if (!redirect) {
loadingFinished = true;
//HIDE LOADING IT HAS FINISHED
} else {
redirect = false;
}
}
});
UPDATE :
Selon la documentation : onPageStarted ne sera PAS appelé lorsque le contenu d'un cadre intégré change, c'est-à-dire en cliquant sur un lien dont la cible est un iframe.
J'ai trouvé un cas spécifique de ce genre sur Twitter où seule une pageFinished était appelée, ce qui a un peu perturbé la logique. Pour résoudre ce problème, j'ai ajouté une tâche planifiée pour supprimer le chargement après X secondes. Ce n'est pas nécessaire dans tous les autres cas.
MISE À JOUR 2 :
Maintenant, avec l'implémentation actuelle de WebView Android :
boolean loadingFinished = true;
boolean redirect = false;
mWebView.setWebViewClient(new WebViewClient() {
@Override
public boolean shouldOverrideUrlLoading(
WebView view, WebResourceRequest request) {
if (!loadingFinished) {
redirect = true;
}
loadingFinished = false;
webView.loadUrl(request.getUrl().toString());
return true;
}
@Override
public void onPageStarted(
WebView view, String url, Bitmap favicon) {
super.onPageStarted(view, url, favicon);
loadingFinished = false;
//SHOW LOADING IF IT ISNT ALREADY VISIBLE
}
@Override
public void onPageFinished(WebView view, String url) {
if (!redirect) {
loadingFinished = true;
//HIDE LOADING IT HAS FINISHED
} else {
redirect = false;
}
}
});
Vous avez probablement remarqué l'avertissement dans la doc de onPageStarted : onPageStarted va PAS soit appelé lorsque le contenu d'un cadre intégré change, c'est-à-dire en cliquant sur un lien dont la cible est un iframe. Cela peut donc fausser la logique dans ces cas-là. BTW, la simplification de @polen fonctionne-t-elle vraiment ?
Jolie prise, je n'avais jamais remarqué le truc du cadre. Je n'ai pas essayé le code de Polen. Le seul que je puisse assurer qui fonctionne, c'est le code ci-dessus que j'utilise.
Juste une petite correction. C'est en fait "public void onPageStarted (WebView view, String url, Bitmap favicon)" au lieu de "public void onPageStarted(WebView view, String url)".
J'ai un faible pour la solution de @NeTeInStEiN (et @polen), mais je l'aurais implémentée avec un compteur au lieu de multiples booléens ou d'observateurs d'état (juste une autre saveur, mais j'ai pensé que je pourrais partager). Il y a une nuance JS à ce sujet, mais je pense que la logique est un peu plus facile à comprendre.
private void setupWebViewClient() {
webView.setWebViewClient(new WebViewClient() {
private int running = 0; // Could be public if you want a timer to check.
@Override
public boolean shouldOverrideUrlLoading(WebView webView, String urlNewString) {
running++;
webView.loadUrl(urlNewString);
return true;
}
@Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
running = Math.max(running, 1); // First request move it to 1.
}
@Override
public void onPageFinished(WebView view, String url) {
if(--running == 0) { // just "running--;" if you add a timer.
// TODO: finished... if you want to fire a method.
}
}
});
}
Votre code semble bon. J'ai essayé la même chose pour ma webview qui se charge à partir de données html et non d'url. Mais celui-ci déclenche le onPageFinished si la première webview se charge rapidement et avant que la seconde ne commence à se charger. Scénario normal. running =1 , running = 2, --running =1 , --running =0 Scénario inhabituel qui échoue - running =1 , --running = 0, running =1 running =0
Il existe également un autre scénario : si un événement n'est pas déclenché pour une raison quelconque, la partie TODO ne sera jamais atteinte. Vous avez donc besoin d'une minuterie pour vérifier les délais d'attente. Ou vous pouvez appeler une fonction java exportée en javascript lorsque vous savez que tout est chargé correctement. Quelque chose comme documentReady() ou quelque chose comme ça.
Si vous voulez afficher une barre de progression, vous devez écouter un événement de changement de progression, et pas seulement l'achèvement de la page :
mWebView.setWebChromeClient(new WebChromeClient(){
@Override
public void onProgressChanged(WebView view, int newProgress) {
//change your progress bar
}
});
Si vous souhaitez afficher une barre de progression indéterminée, il suffit de remplacer la méthode onPageFinished.
J'ai simplifié NeTeInStEiN Le code de l'entreprise doit être comme ça :
mWebView.setWebViewClient(new WebViewClient() {
private int webViewPreviousState;
private final int PAGE_STARTED = 0x1;
private final int PAGE_REDIRECTED = 0x2;
@Override
public boolean shouldOverrideUrlLoading(WebView view, String urlNewString) {
webViewPreviousState = PAGE_REDIRECTED;
mWebView.loadUrl(urlNewString);
return true;
}
@Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
super.onPageStarted(view, url, favicon);
webViewPreviousState = PAGE_STARTED;
if (dialog == null || !dialog.isShowing())
dialog = ProgressDialog.show(WebViewActivity.this, "", getString(R.string.loadingMessege), true, true,
new OnCancelListener() {
@Override
public void onCancel(DialogInterface dialog) {
// do something
}
});
}
@Override
public void onPageFinished(WebView view, String url) {
if (webViewPreviousState == PAGE_STARTED) {
dialog.dismiss();
dialog = null;
}
}
});
C'est facile à comprendre, OnPageFinished si le callback précédent est sur onPageStarted, donc la page est complètement chargée.
Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.
1 votes
Veuillez considérer que ma réponse est correcte, car elle résout certains problèmes que celle de Ian ne résout pas.
0 votes
Je pense qu'il y a un meilleur moyen d'appeler le code java natif avec des js lorsque la page est chargée. Référez-vous à cette réponse, bien que ce soit pour ios, mais l'idée s'applique ici aussi. .
0 votes
Consultez ma réponse ci-dessous pour une solution minimale et concise.
0 votes
Quelqu'un sait-il comment faire cela avec une WebView MAUI ?