Android ProgessBar while loading WebView

AndroidAndroid AsynctaskAndroid WebviewAndroid Progressbar

Android Problem Overview


In my application, I have a WebView which loads any URL from the internet. Now, sometimes due to slow networks the page takes a long time to load and the user sees only a blank screen.

I want to show a ProgressBar while the WebView gets loaded and hide the ProgessBar when the WebView gets loaded completely.

I know how to use the ProgressBar and AsyncTasks, but here is my problem.

This is the code that I use to load my WebView.

	mWebView = (WebView) findViewById(R.id.webview);
	mWebView.getSettings().setJavaScriptEnabled(true);
	mWebView.setWebViewClient(new HelloWebViewClient());
	mWebView.loadUrl(web_URL);
	

And this my custom WebViewClient class

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

Now, if I try to show the ProgressBar using AsyncTasks then I guess I would have to give the code to load the URL in the doInBackGround() function of my AsyncTask and show the progress through the onProgressUpdate() function.

But, how do I load the URL inside the doInBackground() as doInBackground() runs on the Non-UI thread and I wont be able to use mWebView.loadUrl(web_URL) inside it.

Any suggestions? Am I missing something obvious? Please guide me.

Android Solutions


Solution 1 - Android

Check the source code. Help you and solve your problem...

public class AppWebViewClients extends WebViewClient {
	 private ProgressBar progressBar;
	
	public AppWebViewClients(ProgressBar progressBar) {
		this.progressBar=progressBar;
		progressBar.setVisibility(View.VISIBLE);
	}
	@Override
	public boolean shouldOverrideUrlLoading(WebView view, String url) {
		// TODO Auto-generated method stub
		view.loadUrl(url);
		return true;
	}
	
	@Override
	public void onPageFinished(WebView view, String url) {
		// TODO Auto-generated method stub
		super.onPageFinished(view, url);
		progressBar.setVisibility(View.GONE);
	}
}

I think it help you.

Thanks.

Solution 2 - Android

> I want to show a progressBar while the webView gets loaded and hide > the progessBar when the webView gets loaded completely.

Following snippet will help you.

main.xml

<?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 android:id="@+id/webview"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:layout_weight="1" />
</LinearLayout>

Main.class

public class Main extends Activity {
    private WebView webview;
    private static final String TAG = "Main";
    private ProgressDialog progressBar;

    /** Called when the activity is first created. */@Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        requestWindowFeature(Window.FEATURE_NO_TITLE);

        setContentView(R.layout.main);

        this.webview = (WebView) findViewById(R.id.webview);

        WebSettings settings = webview.getSettings();
        settings.setJavaScriptEnabled(true);
        webview.setScrollBarStyle(WebView.SCROLLBARS_OUTSIDE_OVERLAY);

        final AlertDialog alertDialog = new AlertDialog.Builder(this).create();

        progressBar = ProgressDialog.show(Main.this, "Showing ProgressDialog", "Loading...");

        webview.setWebViewClient(new WebViewClient() {
            public boolean shouldOverrideUrlLoading(WebView view, String url) {
                Log.i(TAG, "Processing webview url click...");
                view.loadUrl(url);
                return true;
            }

            public void onPageFinished(WebView view, String url) {
                Log.i(TAG, "Finished loading URL: " + url);
                if (progressBar.isShowing()) {
                    progressBar.dismiss();
                }
            }

            public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {
                Log.e(TAG, "Error: " + description);
                Toast.makeText(Main.this, "Oh no! " + description, Toast.LENGTH_SHORT).show();
                alertDialog.setTitle("Error");
                alertDialog.setMessage(description);
                alertDialog.setButton("OK", new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int which) {
                        return;
                    }
                });
                alertDialog.show();
            }
        });
        webview.loadUrl("http://www.google.com");
    }
}

Solution 3 - Android

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);
        }

Solution 4 - Android

if you want to show the progressbar every time the user loads page (and not only the first load), then you can use this:

MainActivity.java

public class MainActivity extends Activity
{
    private WebView webView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        webView = (WebView) findViewById(R.id.webView);

        final ProgressDialog progressBar = new ProgressDialog(MainActivity.this);
        progressBar.setMessage("Please wait...");

        webView.loadUrl("https://example.org/");
        webView.setWebViewClient(new WebViewClient() {
            public boolean shouldOverrideUrlLoading(WebView view, String url) {
                view.loadUrl(url);
                return true;
            }

            @Override
            public void onPageStarted(WebView view, String url, Bitmap favicon) {
                super.onPageStarted(view, url, favicon);
                if (!progressBar.isShowing()) {
                    progressBar.show();
                }
            }

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

            public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {
                if (progressBar.isShowing()) {
                    progressBar.dismiss();
                }
            }
        });

    }
}

activity_main.xml :

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="0dp"
    android:paddingLeft="0dp"
    android:paddingRight="0dp"
    android:paddingTop="0dp"
    tools:showIn="@layout/activity_main">
    
    <WebView
        android:id="@+id/webView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_alignParentEnd="true"
        android:layout_alignParentLeft="true"
        android:layout_alignParentRight="true"
        android:layout_alignParentStart="true"
        android:layout_alignParentTop="true" />

</RelativeLayout>

Solution 5 - Android

  1. Using WebChromeClient:

    webView.webChromeClient = object: WebChromeClient() {
        override fun onProgressChanged(view: WebView?, newProgress: Int) {
            super.onProgressChanged(view, newProgress)
    
            progressBar?.isVisible = newProgress < 100
            progressBar?.progress = newProgress
        }
    }
    

In this case you can even show determined progress bar.

  1. Using WebViewClient:

     String url = "https://stackoverflow.com/questions/11241513/android-progessbar-while-loading-webview";
     setProgressBarVisibility(View.VISIBLE);
    
     webView.setWebViewClient(new WebViewClient() {
         @Override
         public void onPageStarted(WebView view, String url, Bitmap favicon) {
             super.onPageStarted(view, url, favicon);
             setProgressBarVisibility(View.VISIBLE);
         }
    
         @Override
         public void onPageFinished(WebView view, String url) {
             super.onPageFinished(view, url);
             setProgressBarVisibility(View.GONE);
         }
    
         @Override
         public void onReceivedError(WebView view, WebResourceRequest request, WebResourceError error) {
             super.onReceivedError(view, request, error);
             setProgressBarVisibility(View.GONE);
         }
     });
    
     webView.loadUrl(url);
    

Also add method:

    private void setProgressBarVisibility(int visibility) {
        // If a user returns back, a NPE may occur if WebView is still loading a page and then tries to hide a ProgressBar.
        if (progressBar != null) {
            progressBar.setVisibility(visibility);
        }
    }

Solution 6 - Android

  @SuppressLint("SetJavaScriptEnabled")
private void init() {
    webView = (WebView) findViewById(R.id.kamal);
    webView.setBackgroundColor(0);
    webView.getSettings().setJavaScriptEnabled(true);
    progressDialog = new ProgressDialog(WebView_Ofline.this);
    progressDialog.setMessage("Loading Please wait...");
    progressDialog.setCancelable(false);
    progressDialog.show();
    webView.setWebViewClient(new WebViewClient() {
        public void onPageFinished(WebView view, String url) {
            try {
                progressDialog.dismiss();
            } catch (Exception e) {
                e.printStackTrace();

            }
        }

    });
}

Solution 7 - Android

    myThanh.setScrollBarStyle(WebView.SCROLLBARS_OUTSIDE_OVERLAY);

	final AlertDialog alertDialog = new AlertDialog.Builder(this).create();

	progressBar = ProgressDialog.show(MainActivity.this,"Đang tải dữ liệu",  "Vui lòng chờ...");

	myThanh.setWebViewClient(new WebViewClient() {


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

Solution 8 - Android

This simple solution worked for me in KOTLIN:

private fun setupWebView() {

    val webViewClient: WebViewClient = object: WebViewClient() {

        override fun shouldOverrideUrlLoading(view: WebView?, request: WebResourceRequest?): Boolean {
            view?.loadUrl(request?.url.toString())
            return super.shouldOverrideUrlLoading(view, request)
        }

        override fun onPageStarted(view: WebView?, url: String?, favicon: Bitmap?) {
            showProgressDialog()
            super.onPageStarted(view, url, favicon)
        }

        override fun onPageFinished(view: WebView?, url: String?) {
            hideProgressDialog()
            super.onPageFinished(view, url)
        }
    }
    webView.webViewClient = webViewClient

    webView.settings.javaScriptEnabled = true
    webView.settings.defaultTextEncodingName = "utf-8"
}

Solution 9 - Android

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()

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

        override fun onPageCommitVisible(view: WebView?, url: String?) {
            super.onPageCommitVisible(view, url)
            progressBar.dismiss()
        }
    }

Solution 10 - Android

Paste This in your code and add your URL

   var progressDialog: ProgressDialog? = null

private fun startWebView(url: String) {

    val 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 = ProgressDialog(this)
    progressDialog!!.setMessage("Loading...")
    progressDialog!!.show()

    webView.setWebViewClient(object : WebViewClient() {
        override fun shouldOverrideUrlLoading(view: WebView, url: String): Boolean {
            view.loadUrl(url)
            return true
        }

        override fun onPageFinished(view: WebView, url: String) {
            if (progressDialog!!.isShowing()) {
                progressDialog!!.dismiss()
            }
        }

        override fun onReceivedError(view: WebView, errorCode: Int, description: String, failingUrl: String) {
            Toast.makeText(this@MainActivity, "Error:$description", Toast.LENGTH_SHORT).show()

        }
    })
    webView.loadUrl(url)
}

Solution 11 - Android

You can use something like that:

override fun onPageStarted(view: WebView?, url: String?, favicon: Bitmap?) {
    super.onPageStarted(view, url, favicon)
    binding.pbLoader.visibility = ProgressBar.VISIBLE
}

override fun onPageCommitVisible(view: WebView?, url: String?) {
    super.onPageCommitVisible(view, url)
    binding.pbLoader.visibility = ProgressBar.GONE
}

Solution 12 - Android

    WebView webView;
ProgressDialog progressDialog;

TextView text;
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_web_view);


    String message = getIntent().getStringExtra("key").toString();
    setTitle(message);
    Bundle isNetworkAvailable = getIntent().getExtras();

    String value = "file:///android_asset/n/o/i/no_connection.html";
    if (isNetworkAvailable()) {
        value = isNetworkAvailable.getString("keyHTML");
    }
    webView = (WebView) findViewById(R.id.kamal);
    webView.loadUrl(value);
    init();
}

private boolean isNetworkAvailable() {
    ConnectivityManager connectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
    NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo();
    return activeNetworkInfo != null && activeNetworkInfo.isConnected();
}

private void init() {
    webView = (WebView) findViewById(R.id.kamal);
    webView.getSettings().setBuiltInZoomControls(true);
    webView.setBackgroundColor(0);
    webView.getSettings().setJavaScriptEnabled(true);
    progressDialog = new ProgressDialog(WebView_Online.this);
    progressDialog.setMessage("Loading Please wait...");
    progressDialog.setCancelable(false);
    progressDialog.show();
    webView.setWebViewClient(new WebViewClient() {
        public void onPageFinished(WebView view, String url) {
            try {
                progressDialog.dismiss();
            } catch (Exception e) {
                e.printStackTrace();

            }
        }

    });
}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionSwayamView Question on Stackoverflow
Solution 1 - AndroidMd Abdul GafurView Answer on Stackoverflow
Solution 2 - AndroidVipulView Answer on Stackoverflow
Solution 3 - AndroidIshant GargView Answer on Stackoverflow
Solution 4 - AndroidmedskillView Answer on Stackoverflow
Solution 5 - AndroidCoolMindView Answer on Stackoverflow
Solution 6 - AndroidVIMAL VISHWAKARMAView Answer on Stackoverflow
Solution 7 - AndroidJames HoangView Answer on Stackoverflow
Solution 8 - AndroidMarcelo GraciettiView Answer on Stackoverflow
Solution 9 - AndroidHally TrầnView Answer on Stackoverflow
Solution 10 - AndroidMazRoidView Answer on Stackoverflow
Solution 11 - AndroidMoroView Answer on Stackoverflow
Solution 12 - AndroidVIMAL VISHWAKARMAView Answer on Stackoverflow