Ccna final exam - java, php, javascript, ios, cshap all in one. This is a collaboratively edited question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.
Friday, May 18, 2012
How to listen for a Webview finishing loading a URL in Android?
I have a webview that is loading a page from the Internet. I want to show a progressbar until the loading is complete.
How do I listen for the completion of page loading of a WebView ?
@ian this is not 100% accurate. If you have several iframes in a page you will have multiple onPageFinished (and onPageStarted). And if you have several redirects it may also fail. This approach solves (almost) all the problems:
if(loadingFinished && !redirect){ //HIDE LOADING IT HAS FINISHED } else{ redirect = false; }
} });
UPDATE: I found a specific case on Twitter redirects where (i haven't found out yet why) only a pageFinished was called and messed the logic a bit. To solve that i added a scheduled task to remove loading after X seconds. This is not needed in all the other 99% of cases.
I have simplified NeTeInStEiN's code to be like this:
mWebView.setWebViewClient(new WebViewClient() { private int webViewPreviousState; private final int PAGE_STARTED = 0x1; private final int PAGE_REDIRECTED = 0x2;
You can trace the Progress Staus by the getProgress mehtod in webview class.
Initialize the progress status
private int mProgressStatus = 0;
then the AsyncTask for loading like this:
private class Task_News_ArticleView extends AsyncTask<Void, Void, Void> { private final ProgressDialog dialog = new ProgressDialog( your_class.this);
// can use UI thread here protected void onPreExecute() { this.dialog.setMessage("Loading..."); this.dialog.setCancelable(false); this.dialog.show(); }
Just implement WebViewClient and extend onPageFinished() as follows:
ReplyDeletemWebView.setWebViewClient(new WebViewClient() {
public void onPageFinished(WebView view, String url) {
// do your stuff here
}
});
@ian this is not 100% accurate. If you have several iframes in a page you will have multiple onPageFinished (and onPageStarted). And if you have several redirects it may also fail. This approach solves (almost) all the problems:
ReplyDeleteboolean 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;
}
if(loadingFinished && !redirect){
//HIDE LOADING IT HAS FINISHED
} else{
redirect = false;
}
}
});
UPDATE:
I found a specific case on Twitter redirects where (i haven't found out yet why) only a pageFinished was called and messed the logic a bit. To solve that i added a scheduled task to remove loading after X seconds. This is not needed in all the other 99% of cases.
I have simplified NeTeInStEiN's code to be like this:
ReplyDeletemWebView.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;
}
}
});
It is easy to understand. OnPageFinished if the previouse callBack is onPageStarted, so the page is completely loaded.
If you want show a progress bar you need to listen for a progress change event, not just for the completion of page:
ReplyDeletemWebView.setWebChromeClient(new WebChromeClient(){
@Override
public void onProgressChanged(WebView view, int newProgress) {
//change your progress bar
}
});
BTW if you want display just an Indeterminate ProgressBar overriding the method onPageFinished is enough
Use setWebViewClient() and override onPageFinished()
ReplyDeleteYou can trace the Progress Staus by the getProgress mehtod in webview class.
ReplyDeleteInitialize the progress status
private int mProgressStatus = 0;
then the AsyncTask for loading like this:
private class Task_News_ArticleView extends AsyncTask<Void, Void, Void> {
private final ProgressDialog dialog = new ProgressDialog(
your_class.this);
// can use UI thread here
protected void onPreExecute() {
this.dialog.setMessage("Loading...");
this.dialog.setCancelable(false);
this.dialog.show();
}
@Override
protected Void doInBackground(Void... params) {
try {
while (mProgressStatus < 100) {
mProgressStatus = webview.getProgress();
}
} catch (Exception e) {
}
return null;
}
protected void onPostExecute(Void result) {
if (this.dialog.isShowing()) {
this.dialog.dismiss();
}
}
}