在WebView中添加进度条

62
我想给使用WebView的应用程序添加一个进度/加载条。我对如何实现在每次点击链接时出现进度条感到困惑。
目前的代码:
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);
    }
}

活动布局:

<?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>

你要寻找的答案在这里有非常详细的解释:http://www.giantflyingsaucer.com/blog/?p=1331 - Andres SK
1
可能是Android WebView进度条的重复问题。 - e-sushi
如何在 WebView 上点击按钮时下载 PDF 或 DOC - Akash Dubey
8个回答

85

我在你的代码中添加了几行,现在它能够使用进度条正常工作。

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

2
没有看到你的整个代码,就无法理解。 - Sandy
8
最终,活动activity = this;最终进度条progressDialog = new ProgressDialog(activity); progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL); progressDialog.setCancelable(false);浏览器设置WebChromeClient(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
你为什么同时注册了Chrome客户端和Web客户端? - To Kra
必须使用WebChromeClient吗?我能否使用WebClient代替WebChromeClient? - Pranav P
1
从API 21开始,setProgress()已被弃用。应该怎么办? - soshial
显示剩余9条评论

20

在此方法中传递您的 URL

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

16

在你设置Webview的oncreate方法中。

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

  }
}

1
我尝试了很多代码,但是没有一个能在进度条的webview上运行。但是这个代码很好用,谢谢Nitesh Khosla。 - Nitesh Khosla
代码不变,只需用进度条(progressbar)替换进度对话框(progressdialog)。 - Nitesh Khosla

9
以下是我使用的代码:
在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);
            }

以下是XML代码:

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

希望这能帮助你..

8
我最有效的方法是:
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;
    }
}

2
这个布尔变量isWebViewLoadingFirstPage的目的是什么?在哪里初始化它? - Chandrahasan
onPageStarted非常晚 - 进度旋转器在大部分我想要的时间内都不显示。shouldOverrideUrlLoading(请参见上面的答案https://dev59.com/km855IYBdhLWcg3wc0Dy#57068625)对我来说效果更好。 - Andy Weinstein

7
将进度条和Webview放在一个RelativeLayout中,并按照以下属性设置进度条:
1. 将其可见性设置为GONE。 2. 在RelativeLayout中居中。
然后,在WebClient的onPageStarted()方法中,使进度条可见,以便在单击链接时显示进度条。在onPageFinished()方法中,将进度条的可见性设置为GONE,以便在页面加载完成后消失... 这将适用于您的情况。希望这可以帮助您...

2
我尝试在方法onPageFinished()中取消进度,但效果不太好,它需要延迟一段时间才能渲染webview。
尝试使用onPageCommitVisible()更好:
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
您可以将此代码尝试添加到您的活动中。
    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);
    }

使用以下方式调用此方法:

startWebView(web_view,"Your Url");

有时,如果URL无效,它将被重定向,并在onPageFinished方法之前进入onLoadResource()。因此,进度条将无法消失。要解决此问题,请参见我的这个答案
谢谢 :)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接