Jan*_*usz 422 android android-webview
我有一个WebView从Internet上加载页面.我想显示一个ProgressBar直到加载完成.
我如何监听完成页面加载WebView?
ian*_*ian 686
扩展WebViewClient并调用onPageFinished(),如下所示:
mWebView.setWebViewClient(new WebViewClient() {
public void onPageFinished(WebView view, String url) {
// do your stuff here
}
});
Run Code Online (Sandbox Code Playgroud)
net*_*ein 145
@ian这不是100%准确.如果页面中有多个iframe,则会有多个onPageFinished(和onPageStarted).如果你有几个重定向,它也可能会失败.这种方法解决了(几乎)所有问题:
boolean loadingFinished = true;
boolean redirect = false;
mWebView.setWebViewClient(new WebViewClient() {
@Override
public boolean shouldOverrideUrlLoading(WebView view, String urlNewString) {
if (!loadingFinished) {
redirect = true;
}
loadingFinished = false;
webView.loadUrl(urlNewString);
return true;
}
@Override
public void onPageStarted(WebView view, String url) {
loadingFinished = false;
//SHOW LOADING IF IT ISNT ALREADY VISIBLE
}
@Override
public void onPageFinished(WebView view, String url) {
if (!redirect) {
loadingFinished = true;
//HIDE LOADING IT HAS FINISHED
} else {
redirect = false;
}
}
});
Run Code Online (Sandbox Code Playgroud)
更新:
根据文档:当嵌入框架的内容发生变化时,不会调用onPageStarted,即单击目标为iframe的链接.
我在Twitter上发现了一个特定的案例,其中只有一个pageFinished被调用并且稍微搞乱了逻辑.为了解决这个问题,我添加了一个计划任务,在X秒后删除加载.在所有其他情况下都不需要这样做.
更新2:
现在使用当前的Android WebView实现:
boolean loadingFinished = true;
boolean redirect = false;
mWebView.setWebViewClient(new WebViewClient() {
@Override
public boolean shouldOverrideUrlLoading(
WebView view, WebResourceRequest request) {
if (!loadingFinished) {
redirect = true;
}
loadingFinished = false;
webView.loadUrl(request.getUrl().toString());
return true;
}
@Override
public void onPageStarted(
WebView view, String url, Bitmap favicon) {
super.onPageStarted(view, url, favicon);
loadingFinished = false;
//SHOW LOADING IF IT ISNT ALREADY VISIBLE
}
@Override
public void onPageFinished(WebView view, String url) {
if (!redirect) {
loadingFinished = true;
//HIDE LOADING IT HAS FINISHED
} else {
redirect = false;
}
}
});
Run Code Online (Sandbox Code Playgroud)
Sci*_*ear 40
我非常偏爱@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.
}
}
});
}
Run Code Online (Sandbox Code Playgroud)
pol*_*len 23
我简化了NeTeInStEiN的代码是这样的:
mWebView.setWebViewClient(new WebViewClient() {
private int webViewPreviousState;
private final int PAGE_STARTED = 0x1;
private final int PAGE_REDIRECTED = 0x2;
@Override
public boolean shouldOverrideUrlLoading(WebView view, String urlNewString) {
webViewPreviousState = PAGE_REDIRECTED;
mWebView.loadUrl(urlNewString);
return true;
}
@Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
super.onPageStarted(view, url, favicon);
webViewPreviousState = PAGE_STARTED;
if (dialog == null || !dialog.isShowing())
dialog = ProgressDialog.show(WebViewActivity.this, "", getString(R.string.loadingMessege), true, true,
new OnCancelListener() {
@Override
public void onCancel(DialogInterface dialog) {
// do something
}
});
}
@Override
public void onPageFinished(WebView view, String url) {
if (webViewPreviousState == PAGE_STARTED) {
dialog.dismiss();
dialog = null;
}
}
});
Run Code Online (Sandbox Code Playgroud)
很容易理解,OnPageFinished如果前一个回调是在onPageStarted上,那么页面是完全加载的.
Fra*_*ita 17
如果您想要显示进度条,则需要监听进度更改事件,而不仅仅是完成页面:
mWebView.setWebChromeClient(new WebChromeClient(){
@Override
public void onProgressChanged(WebView view, int newProgress) {
//change your progress bar
}
});
Run Code Online (Sandbox Code Playgroud)
顺便说一下,如果你想只显示一个Indeterminate ProgressBar,那么覆盖onPageFinished方法就足够了
Sky*_*net 17
我找到了一个优雅的解决方案,但没有经过严格的测试:
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
if (m_webView.getProgress() == 100) {
progressBar.setVisibility(View.GONE);
m_webView.setVisibility(View.VISIBLE);
}
}
Run Code Online (Sandbox Code Playgroud)
对于 Kotlin 用户:
webView.webViewClient = object : WebViewClient() {
override fun onPageFinished(view: WebView?, url: String?) {
// do your logic
}
}
Run Code Online (Sandbox Code Playgroud)
有很多方法可以重写
您可以通过webview类中的getProgress方法跟踪Progress Staus .
初始化进度状态
private int mProgressStatus = 0;
Run Code Online (Sandbox Code Playgroud)
然后像这样加载AsyncTask:
private class Task_News_ArticleView extends AsyncTask<Void, Void, Void> {
private final ProgressDialog dialog = new ProgressDialog(
your_class.this);
// can use UI thread here
protected void onPreExecute() {
this.dialog.setMessage("Loading...");
this.dialog.setCancelable(false);
this.dialog.show();
}
@Override
protected Void doInBackground(Void... params) {
try {
while (mProgressStatus < 100) {
mProgressStatus = webview.getProgress();
}
} catch (Exception e) {
}
return null;
}
protected void onPostExecute(Void result) {
if (this.dialog.isShowing()) {
this.dialog.dismiss();
}
}
}
Run Code Online (Sandbox Code Playgroud)
谢谢你的回答.它帮助了我,但我必须根据我的需要改进它.我有几个页面和完成,所以我添加了一个计时器,检查是否启动了pagefinish新的pagestart.好的,不好的解释.看代码:)
myWebView.setWebViewClient(new WebViewClient() {
boolean loadingFinished = true;
boolean redirect = false;
long last_page_start;
long now;
// Load the url
public boolean shouldOverrideUrlLoading(WebView view, String url) {
if (!loadingFinished) {
redirect = true;
}
loadingFinished = false;
view.loadUrl(url);
return false;
}
@Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
Log.i("p","pagestart");
loadingFinished = false;
last_page_start = System.nanoTime();
show_splash();
}
// When finish loading page
public void onPageFinished(WebView view, String url) {
Log.i("p","pagefinish");
if(!redirect){
loadingFinished = true;
}
//call remove_splash in 500 miSec
if(loadingFinished && !redirect){
now = System.nanoTime();
new android.os.Handler().postDelayed(
new Runnable() {
public void run() {
remove_splash();
}
},
500);
} else{
redirect = false;
}
}
private void show_splash() {
if(myWebView.getVisibility() == View.VISIBLE) {
myWebView.setVisibility(View.GONE);
myWebView_splash.setVisibility(View.VISIBLE);
}
}
//if a new "page start" was fired dont remove splash screen
private void remove_splash() {
if (last_page_start < now) {
myWebView.setVisibility(View.VISIBLE);
myWebView_splash.setVisibility(View.GONE);
}
}
});
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
306692 次 |
| 最近记录: |