When displaying web content using Android’s WebView, it’s a common UX requirement to show a loading indicator while the page is being loaded. Users expect visual feedback — especially when network latency or complex pages delay rendering.
This guide shows how to implement a ProgressBar with WebView so that a spinner or horizontal progress bar appears while a page loads and hides once loading completes.
Why Show a Progress Bar with WebView
A WebView loads content asynchronously. Without feedback, users may think the app is unresponsive, especially on slow connections.
A progress indicator:
- Improves perceived performance
- Communicates loading progress or state
- Offers better engagement and polish
Whether you use a spinner or a horizontal bar depends on your app’s design.
Add WebView and ProgressBar in Layout
Here’s a simple layout (activity_main.xml) that combines a ProgressBar and WebView:
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ProgressBar
android:id="@+id/progressBar"
style="@android:style/Widget.DeviceDefault.Light.ProgressBar.Large"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:visibility="gone"/>
<WebView
android:id="@+id/webView"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</FrameLayout>
Notes
FrameLayoutallows stacking the progress bar over the WebView- The
ProgressBarstarts as gone and is shown while loading
Configure WebView Settings
In your Activity’s onCreate(), configure the WebView:
WebView webView = findViewById(R.id.webView);
WebSettings webSettings = webView.getSettings();
webSettings.setJavaScriptEnabled(true); // Enable JavaScript if needed
webSettings.setDomStorageEnabled(true); // Support modern sites
These settings improve compatibility with most web content.
Show/HIDE ProgressBar Using WebViewClient
The key to showing a ProgressBar while a page loads is WebViewClient callbacks:
ProgressBar progressBar = findViewById(R.id.progressBar);
webView.setWebViewClient(new WebViewClient() {
@Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
super.onPageStarted(view, url, favicon);
progressBar.setVisibility(View.VISIBLE);
}
@Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
progressBar.setVisibility(View.GONE);
}
});
Explanation
onPageStartedshows the indicator before the page begins loadingonPageFinishedhides the indicator after the content is rendered
This simple pattern provides clean feedback without blocking the UI.
Load Your URL
After setting the client:
String url = "https://www.example.com";
webView.loadUrl(url);
The progress bar now appears only while the page is loading.
Optional: Show Load Progress Percent
If you want to show a horizontal progress bar with percentage, use WebChromeClient:
Layout (Horizontal ProgressBar)
<ProgressBar
android:id="@+id/progressBarHorizontal"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="match_parent"
android:layout_height="4dp"
android:max="100"
android:visibility="gone"/>
Code
webView.setWebChromeClient(new WebChromeClient() {
@Override
public void onProgressChanged(WebView view, int newProgress) {
if (newProgress < 100) {
progressBarHorizontal.setVisibility(View.VISIBLE);
progressBarHorizontal.setProgress(newProgress);
} else {
progressBarHorizontal.setVisibility(View.GONE);
}
}
});
This gives users continuous feedback as pages download and render.
Handling Errors Gracefully
You can detect load errors and show fallback UI:
@Override
public void onReceivedError(WebView view, WebResourceRequest request, WebResourceError error) {
super.onReceivedError(view, request, error);
progressBar.setVisibility(View.GONE);
Toast.makeText(context, "Failed to load content", Toast.LENGTH_SHORT).show();
}
This improves resilience under poor network conditions.
WebView Lifecycle Considerations
To avoid memory leaks and assure proper cleanup:
@Override
protected void onDestroy() {
if (webView != null) {
webView.loadUrl("about:blank");
webView.clearHistory();
webView.removeAllViews();
webView.destroy();
}
super.onDestroy();
}
Proper teardown avoids leaking references and reduces unexpected behavior.
Best Practices (Senior Engineering Insight)
From real Android engineering experience:
- Use WebChromeClient for progress percent feedback
- Only enable JavaScript if needed for your content
- Use app-specific UI patterns for network and load states
- Avoid blocking the main thread — WebView loads asynchronously
- Provide fallback screens for offline or error states
These practices ensure robust and professional user experiences.
Common Issues and Fixes
Progress bar doesn’t show:
✔ Confirm that WebViewClient is set before loadUrl()
✔ Ensure progress bar’s visibility is controlled on UI thread
WebView displays blank page:
✔ Enable JavaScript and DOM storage if needed
✔ Check network permissions (INTERNET) in AndroidManifest.xml
Memory leak after rotation:
✔ Manage WebView lifecycle carefully or use a retained Fragment
Summary
Displaying a ProgressBar while loading WebView content enhances user experience by signaling activity and avoiding perceived delays. Use:
- A
ViewFlipperfor layered UI or stacked indicators WebViewClientfor show/hide logicWebChromeClientfor progress percentage- Proper lifecycle handling to avoid leaks
This pattern builds confident, smooth web-enabled screens in Android apps.


