【问题标题】:Android ProgessBar while loading WebView加载 WebView 时的 Android 进度条
【发布时间】:2012-06-29 18:55:24
【问题描述】:

在我的应用程序中,我有一个 WebView,它可以从 Internet 加载任何 URL。现在,有时由于网络速度较慢,页面需要很长时间才能加载,用户只能看到一个空白屏幕。

我想在WebView 加载时显示ProgressBar,并在WebView 完全加载时隐藏ProgessBar。

我知道如何使用ProgressBar 和AsyncTasks,但这是我的问题。

这是我用来加载我的WebView 的代码。

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

这是我的自定义 WebViewClient 类

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

现在,如果我尝试 使用 AsyncTasks 显示 ProgressBar,那么我想我将不得不在我的 @987654338 的 doInBackGround() 函数中提供加载 URL 的代码@ 并通过onProgressUpdate() 函数显示进度。

但是,当 doInBackground() 在 非 UI 线程 上运行时,我如何在 doInBackground() 中加载 URL,我将无法使用 @987654340 @在里面。

有什么建议吗?我错过了一些明显的东西吗?请指导我。

【问题讨论】:

标签: android android-asynctask android-webview android-progressbar


【解决方案1】:
  1. 使用WebChromeClient:

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

在这种情况下,您甚至可以显示确定的进度条。

  1. 使用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);
    

同时添加方法:

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

【讨论】:

    【解决方案2】:

    你可以使用类似的东西:

    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
    }
    

    【讨论】:

      【解决方案3】:

      将其粘贴到您的代码中并添加您的 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)
      }
      

      【讨论】:

        【解决方案4】:

        我尝试关闭方法 onPageFinished() 的进度,但效果不佳,渲染 webview 有时间延迟。

        更好地尝试 onPageCommitVisible():

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

        【讨论】:

          【解决方案5】:
            @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();
          
                      }
                  }
          
              });
          }
          

          【讨论】:

          • 你能解释一下吗
          【解决方案6】:
              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();
          
                      }
                  }
          
              });
          }
          

          【讨论】:

            【解决方案7】:

            如果您想在用户每次加载页面时显示进度条(而不仅仅是第一次加载),那么您可以使用这个:

            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>
            

            【讨论】:

              【解决方案8】:

              这个简单的解决方案在 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"
              }
              

              【讨论】:

              • 有时,似乎不会为每个 onPageStarted 调用调用 onPageFinished,因此当发生 hide 调用时,增加的 showLoading 指示器计数器会减少,从而在屏幕上留下加载指示器。在 Galaxy S4(Android 5.0.1 - WebView Client 版本 51.0.2704.81)和 Nougat 驱动的设备上发生在我身上。
              【解决方案9】:
                  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();
                          }
                      }
                  });
              

              【讨论】:

                【解决方案10】:

                在这个方法中传递你的网址

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

                【讨论】:

                  【解决方案11】:

                  我想在加载和隐藏 webView 时显示一个进度条 webView 完全加载时的 progessBar。

                  跟随sn-p会帮助你。

                  ma​​in.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");
                      }
                  }
                  

                  【讨论】:

                  【解决方案12】:

                  检查源代码。帮助您并解决您的问题...

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

                  我觉得对你有帮助。

                  谢谢。

                  【讨论】:

                  • 为什么需要调用方法shouldOverrideUrlLoading?
                  • shouldOverrideUrlLoading 现已弃用:N 开发者预览版具有此方法签名:public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request)
                  • Thanx..它就像一个魅力,所以一个为你竖起大拇指!
                  • @winklerrr,为了在 WebView 中保持页面导航,因此在应用程序中,我们需要创建一个 WebViewClient 的子类,并覆盖它的 shouldOverrideUrlLoading(WebView webView, String url) 方法。
                  • docs 用于您提到的已弃用方法以及较新版本,特别是 Do not call WebView#loadUrl(String) with the request's URL and then return true. This unnecessarily cancels the current load and starts a new load with the same URL. The correct way to continue loading a given URL is to simply return false, without calling WebView#loadUrl(String)
                  猜你喜欢
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 2018-01-01
                  • 1970-01-01
                  • 2014-05-10
                  • 1970-01-01
                  • 1970-01-01
                  相关资源
                  最近更新 更多