'How to detect when Android WebView has loaded page?

I have an app that displays a splash page and removed that splash page when a URL is loaded in WebView. The following is the relevant code we are using to remove the splash page:

browser.setWebViewClient(new BrowserClient() {
 @Override
 public void onPageFinished(WebView view, String url) {
  super.onPageFinished(view, url);
  // Work around for WebView onPageFinished called twice                
  if (flag == true) {
   browser.setVisibility(View.VISIBLE);
   splashImage.setVisibility(View.INVISIBLE);
   pageLoader.setVisibility(View.INVISIBLE);
  } else {
   flag = true;
  }
 }
});

This code works... except it is slow. The splash page takes far too long to remove, long after the webpage has loaded.

Are there any tips on how I can reliably detect when WebView has loaded a page? I've been researching this for the past few days and I can't seem to come up with anything that is reliable.

The most promising I saw is the following, but putting this code throws an error in Android Console:

@Override
public void invalidate() {
 super.invalidate();

 if (getContentHeight() > 0) {
  // WebView has displayed some content and is scrollable.
 }
}

Thanks!

EDIT: There are a lot of answers proposing onPageFinished, and even someone marking this as a duplicate with a link to solutions using onPageFinished. Folks, we already are using onPageFinished. We are looking for an alternative to onPageFinished due to how unreliable it is.



Solution 1:[1]

If you need than you can achieve this by loaded page progress on using this web client, you can use this also.

 webView.setWebChromeClient(new WebChromeClient() {
                public void onProgressChanged(WebView view, int progress) {
                   Log.e("progress", ""+progress);
                   if (progress == 100) { //...page is fully loaded.
                     // TODO - Add whatever code you need here based on web page load completion...                  
                   } 
                }
            });

Solution 2:[2]

You should use WebChromeClient.onProgressChanged() to obtain the current progress of loading a page.

Solution 3:[3]

If the splash screen you are using is a simple static image then perhaps you can try the following approach:

  1. In XML nest the splash screen (ImageView) inside the WebView:

    <WebView android:id="@+id/wv_your_web_view_id"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
    
        <ImageView android:id="@+id/iv_your_splash_screen_id"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:src="@mipmap/img_the_coolest_image_ever"
            android:contentDescription="@string/splash_screen_desc"/>
    </WebView>
    
  2. Now for the runtime code:

    WebView wvUltimo = findViewById(R.id.wv_your_web_view_id);
    wvUltimo.loadUrl(REQUESTED_WEB_PAGE_URL);   // e.g. "https://www.google.com"
    wvUltimo.getSettings().setJavaScriptEnabled(true);   // Only enable this if you need Javascript to work within the WebView!!
    wvUltimo.setWebChromeClient(new WebChromeClient() {
        public void onProgressChanged(WebView view, int progress) {
            // Log.d(TAG + " 185", "Load Status: " + progress);
            if (progress == 100) {
                ImageView ivCoolSplash = view.findViewById(R.id.iv_your_splash_screen_id);
                ivCoolSplash.setVisibility(View.GONE);
            }
        }
    });
    

... this guarantees that you have direct access to your splash screen from within your WebView and thus can deactivate or hide it instantly when the web page you requested is ready to be viewed.

Solution 4:[4]

This can be done with the use of WebViewClient() to the webview.

Reference : How can I know that my WebView is loaded 100%?

Solution 5:[5]

Xamarin/MAUI solution (see OnPageFinished):

webView.SetWebViewClient(new CustomWebViewClient());

...

public class CustomWebViewClient : WebViewClient
{
    public CustomWebViewClient()
    {
    }

    public override void OnPageFinished(Android.Webkit.WebView view, string url)
    {
        base.OnPageFinished(view, url);

        // Your Logic comes here
    }
}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 SilSur
Solution 2 Diego Torres Milano
Solution 3
Solution 4 TharakaNirmana
Solution 5 ADM-IT