我有一个WebView正在从互联网加载一个页面。我想显示一个ProgressBar,直到加载完成。

我如何监听WebView页面加载的完成?


当前回答

我非常倾向于@NeTeInStEiN(和@polen)解决方案,但会用一个计数器来实现它,而不是多个布尔值或状态监视器(只是另一种风格,但我认为可能会共享)。它确实有一个JS的细微差别,但我觉得逻辑是更容易理解一点。

private void setupWebViewClient() {
    webView.setWebViewClient(new WebViewClient() {
        private int running = 0; // Could be public if you want a timer to check.

        @Override
        public boolean shouldOverrideUrlLoading(WebView webView, String urlNewString) {
            running++;
            webView.loadUrl(urlNewString);
            return true;
        }

        @Override
        public void onPageStarted(WebView view, String url, Bitmap favicon) {
            running = Math.max(running, 1); // First request move it to 1.
        }

        @Override
        public void onPageFinished(WebView view, String url) {
            if(--running == 0) { // just "running--;" if you add a timer.
                // TODO: finished... if you want to fire a method.
            }
        }
    });
}

其他回答

只是为了显示进度条,“onpagstarted”和“onPageFinished”方法就足够了;但如果你想有一个“is_loading”标志(以及页面重定向,…),这个方法可以执行非排序,如“onpagstarted > onpagstarted > onPageFinished > onPageFinished”队列。

但与我的短测试(自己测试),“onProgressChanged”方法值队列是“0-100 > 0-100 > 0-100 >…”

private boolean is_loading = false;

webView.setWebChromeClient(new MyWebChromeClient(context));

private final class MyWebChromeClient extends WebChromeClient{
    @Override
    public void onProgressChanged(WebView view, int newProgress) {
        if (newProgress == 0){
            is_loading = true;
        } else if (newProgress == 100){
            is_loading = false;
        }
        super.onProgressChanged(view, newProgress);
    }
}

如果活动关闭是一个静态变量,也要在活动关闭时设置“is_loading = false”,因为活动可以在页面结束之前完成。

使用setWebViewClient()并重写onPageFinished()

扩展WebViewClient并调用onPageFinished()如下所示:

mWebView.setWebViewClient(new WebViewClient() {

   public void onPageFinished(WebView view, String url) {
        // do your stuff here
    }
});

芬兰湾的科特林解决方案 第一个解决方案是创建webviewclient作为私有类,这是更有效的。 另一方面,第二个解决方案是sorter:)

第一个解决方案

class MainActivity : AppCompatActivity() {
  override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)
    val webView : WebView = findViewById(R.id.webView)
    webView.webViewClient = MyWebViewClient()
 }

private class MyWebViewClient : WebViewClient() {
    override fun onPageStarted(view: WebView?, url: String?, favicon: Bitmap?) {
        println("Load Started")
    }
    override fun onPageFinished(view: WebView, url: String) {
        println("Load Finished")
    }
  }
}

第二个解决方案

class MainActivity : AppCompatActivity() {
  override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)
    val webView : WebView = findViewById(R.id.webView)
    webView.webViewClient = object : WebViewClient() {
        override fun onPageStarted(view: WebView?, url: String?, favicon: Bitmap?) {
            println("Load Started")
        }
        override fun onPageFinished(view: WebView, url: String) {
            println("Load Finished")
        }
     }
 }

两个解其实是一样的。所以onpagstarted函数在页面开始加载时运行,另一个挂onPageFinished函数在页面完全加载时工作。你可能想在onPageFinished函数里面写一个loadFinishedRun()函数的例子。

迟到总比不到好

我发现了一个优雅的解决方案,虽然没有严格测试:

public void onPageFinished(WebView view, String url) {
            super.onPageFinished(view, url);
            if (webView.getProgress() == 100) {
                progressBar.setVisibility(View.GONE);
                webView.setVisibility(View.VISIBLE);
            }
        }