56

I am trying to add a progress/loading bar to my application that uses WebView. I am confused on how to implement a progress bar that appears every time a link is clicked.

Current code:

public class CULearnBrowser extends Activity {

    WebView webview;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        webview = (WebView) findViewById(R.id.webview);
        webview.setWebViewClient(new HelloWebViewClient());
        webview.getSettings().setJavaScriptEnabled(true);
        webview.loadUrl("https://culearn.colorado.edu/webct/entryPageIns.dowebct");
    }

    private class HelloWebViewClient extends WebViewClient {
        @Override
        public boolean shouldOverrideUrlLoading(WebView view, String url) {
            view.loadUrl(url);
            return true;
        }
    }

    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if ((keyCode == KeyEvent.KEYCODE_BACK) && webview.canGoBack()) {
            webview.goBack();
            return true;
        }
        return super.onKeyDown(keyCode, event);
    }
}

Activity layout:

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent">

    <WebView  xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/webview"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent" />

    <TextView  
        android:layout_width="fill_parent" 
        android:layout_height="wrap_content" 
        android:text="@string/hello" />
</LinearLayout>
Vadim Kotov
  • 7,103
  • 8
  • 44
  • 57
Sean
  • 807
  • 1
  • 11
  • 20

8 Answers8

80

I have added few lines in your code and now its working fine with progress bar.

        getWindow().requestFeature(Window.FEATURE_PROGRESS);
        setContentView(R.layout.main );
        // Makes Progress bar Visible
        getWindow().setFeatureInt( Window.FEATURE_PROGRESS, Window.PROGRESS_VISIBILITY_ON);

        webview = (WebView) findViewById(R.id.webview);
        webview.setWebChromeClient(new WebChromeClient() {
            public void onProgressChanged(WebView view, int progress)   
            {
                //Make the bar disappear after URL is loaded, and changes string to Loading...
                setTitle("Loading...");
                setProgress(progress * 100); //Make the bar disappear after URL is loaded
     
                // Return the app name after finish loading
                if(progress == 100)
                   setTitle(R.string.app_name);
                }
            });
        webview.setWebViewClient(new HelloWebViewClient());
        webview.getSettings().setJavaScriptEnabled(true);
        webview.loadUrl("http://www.google.com");
Ishaan Garg
  • 2,819
  • 3
  • 22
  • 27
Sandy
  • 6,040
  • 15
  • 64
  • 87
  • ive seen stuff like that but i dont know how to do it with my code – Sean Dec 02 '10 at 03:49
  • 1
    Without seeing your whole code, It is not possible to understand. – Sandy Dec 02 '10 at 03:52
  • ive attached the xml this is the only other file – Sean Dec 02 '10 at 04:12
  • the progress bar should only be implemented in the java code i feel like – Sean Dec 02 '10 at 04:12
  • It is working on my system. I can give you the whole sample code. – Sandy Dec 02 '10 at 08:19
  • Is it possible to display a spinner in the center of the webview instead of the progress bar while the URL is loading? – Arunabh Das Jan 26 '11 at 12:18
  • 7
    final Activity activity = this; final ProgressDialog progressDialog = new ProgressDialog(activity); progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL); progressDialog.setCancelable(false); browser.setWebChromeClient(new WebChromeClient() { public void onProgressChanged(WebView view, int progress) { progressDialog.show(); progressDialog.setProgress(0); activity.setProgress(progress * 1000); progressDialog.incrementProgressBy(progress); if(progress == 100 && progressDialog.isShowing()) progressDialog.dismiss(); } }); – Sandy Sep 07 '11 at 06:13
  • @Sandy +1 Great answer. Both solutions are working like a charm. I would suggest adding your last comment as an alternative to your solution. – Baz Jan 17 '13 at 12:00
  • why do you have chrome client & even web client registered ? – To Kra Mar 17 '15 at 18:50
  • is it compulsory to use WebChromeClient?Can i use Webclient instead of WebChromeClient??? – realpranav Jul 02 '15 at 07:11
  • 1
    `setProgress()` is deprecated starting with API 21. What to do? – soshial Mar 10 '17 at 11:28
  • @soshial: You can create custom progress bar and show/hide as per usage. – Sandy Mar 14 '17 at 06:11
  • @PratikButaniAndroidDev: You can use code sample which I had pasted here. Link may be down. – Sandy Jun 27 '19 at 05:40
  • @Sandy `new HelloWebViewClient()` also missing. Its tough to understand for newbie. please post it and remove invalid redirection. – Pratik Butani Jun 27 '19 at 06:04
19

pass your url in this method

private void startWebView(String url) {

        WebSettings settings = webView.getSettings();

        settings.setJavaScriptEnabled(true);
        webView.setScrollBarStyle(View.SCROLLBARS_OUTSIDE_OVERLAY);

        webView.getSettings().setBuiltInZoomControls(true);
        webView.getSettings().setUseWideViewPort(true);
        webView.getSettings().setLoadWithOverviewMode(true);

        progressDialog = new ProgressDialog(ContestActivity.this);
        progressDialog.setMessage("Loading...");
        progressDialog.show();

        webView.setWebViewClient(new WebViewClient() {
            @Override
            public boolean shouldOverrideUrlLoading(WebView view, String url) {
                view.loadUrl(url);
                return true;
            }

            @Override
            public void onPageFinished(WebView view, String url) {
                if (progressDialog.isShowing()) {
                    progressDialog.dismiss();
                }
            }

            @Override
            public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {
                Toast.makeText(ContestActivity.this, "Error:" + description, Toast.LENGTH_SHORT).show();

            }
        });
        webView.loadUrl(url);
    }
Ishant Garg
  • 689
  • 7
  • 5
15

in oncreate method where you have set your Webview.

@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);

this.requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.web_view);

web_view = (WebView) findViewById(R.id.web_view);
pd = new ProgressDialog(SiteOpenInWebView.this);
    pd.setMessage("Please wait Loading...");
    pd.show();
    web_view.setWebViewClient(new MyWebViewClient());
    web_view.loadUrl("ur site name");
 }

WebViewClient

private class MyWebViewClient extends WebViewClient {
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
    view.loadUrl(url);

    if (!pd.isShowing()) {
        pd.show();
    }

    return true;
}

@Override
public void onPageFinished(WebView view, String url) {
    System.out.println("on finish");
    if (pd.isShowing()) {
        pd.dismiss();
    }

  }
}
realpranav
  • 1,777
  • 14
  • 34
duggu
  • 35,841
  • 11
  • 112
  • 110
8

Here is the code that I am using:

Inside WebViewClient:

               @Override
             public void onPageStarted(WebView view, String url, Bitmap favicon) {

              super.onPageStarted(view, url, favicon);
              findViewById(R.id.progress1).setVisibility(View.VISIBLE);
             }

            @Override
            public void onPageFinished(WebView view, String url) {
                findViewById(R.id.progress1).setVisibility(View.GONE);
            }

Here is the XML :

<ProgressBar
    android:id="@+id/progress1"
    android:layout_centerHorizontal="true"
    android:layout_centerVertical="true"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content" />

Hope this helps..

nijas
  • 1,839
  • 2
  • 14
  • 13
8

The best approch which worked for me is

webView.setWebViewClient(new WebViewClient() {

    @Override public void onPageStarted(WebView view, String url, Bitmap favicon) {
          super.onPageStarted(view, url, favicon);
          mProgressBar.setVisibility(ProgressBar.VISIBLE);
          webView.setVisibility(View.INVISIBLE);
        }

    @Override public void onPageCommitVisible(WebView view, String url) {
      super.onPageCommitVisible(view, url);
      mProgressBar.setVisibility(ProgressBar.GONE);
      webView.setVisibility(View.VISIBLE);
      isWebViewLoadingFirstPage=false;
    }
}
shekar
  • 1,151
  • 4
  • 21
  • 29
  • 2
    What is the purpose of this boolean isWebViewLoadingFirstPage, where to initialize this ? – Chandrahasan May 04 '17 at 06:07
  • onPageStarted is very late - the progress spinner doesn't show for most of the time I want it to. shouldOverrideUrlLoading (see answer above https://stackoverflow.com/a/57068625/826946) works better for me – Andy Weinstein Dec 09 '19 at 15:24
7

Put a progress bar and the webview inside a relativelayout and set the properties for the progress bar as follows,

  1. Make its visibility as GONE.
  2. CENTRE it in the Relativelayout.

and then in onPageStarted() of the webclient make the progress bar visible so that it shows the progressbar when you have clicked on a link. In onPageFinished() make the progress bar visiblility as GONE so that it disappears when the page has finished loading... This will work fine for your scenario. Hope this helps...

AjOnFire
  • 2,818
  • 3
  • 23
  • 39
2

I try dismis progress on method onPageFinished(), but not good too much, it has time delay to render webview.

try with onPageCommitVisible() better:

val progressBar = ProgressDialog(context)
    progressBar.setCancelable(false)
    progressBar.show()
    val url = "your url here"
    web_container.settings.javaScriptEnabled = true
    web_container.loadUrl(url)

    web_container.webViewClient = object : WebViewClient() {
        override fun shouldOverrideUrlLoading(view: WebView, url: String): Boolean {
            view.loadUrl(url)
            progressBar.show()
            return true
        }

        override fun onPageFinished(view: WebView?, url: String?) {
            super.onPageFinished(view, url)
        }
        override fun onPageCommitVisible(view: WebView?, url: String?) {
            super.onPageCommitVisible(view, url)
            progressBar.dismiss()
        }
    }
    web_container.setOnKeyListener(View.OnKeyListener { _, keyCode, event ->
        if (keyCode == KEYCODE_BACK && event.action == MotionEvent.ACTION_UP
                && web_container.canGoBack()) {
            web_container.goBack()
            return@OnKeyListener true
        }
        return@OnKeyListener false
    })
1

You can try this code into your activity

    private void startWebView(WebView webView,String url) {
 webView.setWebViewClient(new WebViewClient() {
            ProgressDialog progressDialog;

            public boolean shouldOverrideUrlLoading(WebView view, String url) {
                view.loadUrl(url);
                return false;
            }

            @Override
            public void onPageStarted(WebView view, String url, Bitmap favicon) {
                super.onPageStarted(view, url, favicon);
            }

            public void onLoadResource (WebView view, String url) {

                    if (progressDialog == null) {
                        progressDialog = new ProgressDialog(SponceredDetailsActivity.this);
                        progressDialog.setMessage("Loading...");
                        progressDialog.show();
                    }

            }
            public void onPageFinished(WebView view, String url) {
                try{
                    if (progressDialog.isShowing()) {
                        progressDialog.dismiss();
                        progressDialog = null;
                    }

                }catch(Exception exception){
                    exception.printStackTrace();
                }
            }

        });

        webView.getSettings().setJavaScriptEnabled(true);
        webView.loadUrl(url);
    }

Call this method using this way:

startWebView(web_view,"Your Url");

Sometimes if URL is dead it will redirected and it will come to onLoadResource() before onPageFinished method. For this reason progress bar will not dismis. To solve this issue see my this Answer.

Thanks :)

Community
  • 1
  • 1
Md. Sajedul Karim
  • 6,263
  • 3
  • 47
  • 77