Is there a listener for when the WebView displays

2019-01-03 09:09发布

Using WebViewClient and/or the WebChromeClient you can get a listener for when the page has loaded, however this is sometimes called before the WebView has any content in it, before it has displayed anything.

What would be a efficient method for determining when the WebView has displayed it's content?

Edit: (Trying to be more clear)

When I load a page in a WebView, I want to set the scroll to a specific position. It seems that the scroll position cannot be set until the page is loaded and it has an actual content height. So, I have tried two different approaches to determining when the page has finished loading, onPageFinished() from the WebViewClient and also onProgressChanged() from the WebChromeClient. Both of these tell me when the page has finished loading.

However, the problem is that sometimes it is called before the page has been displayed and therefore the page has no height and the scroll call does nothing.

I am trying to find a solid way to determine when the page is ready to be scrolled, ie. when it has its content height.

I imagine I could setup a checking loop after it finished loading to keep looking for when the height is available but that seemed like quite the hack. Hoping there is a cleaner way.

11条回答
Fickle 薄情
2楼-- · 2019-01-03 10:00

I created a custom view extends webview, which overrides the "onSizeChanged" method. The onSizeChanged happens after the webview loads everything in it.

查看更多
等我变得足够好
3楼-- · 2019-01-03 10:01

I read this discussion, and I'm facing the same problem too.

I searched a lot, but they're not the solution they promise to be.

And I don't want to use the deprecated `onNewPicture` callback.

In my own situation I only need to restore the `WebView` scroll position when the activity is started, and I think this is the most cases since when the activity task stack goes to background, Android automatically save the `WebView` state, so when it pops to the foreground, it will looks the same. If it gets killed when under background, I'm sure you'll manage to save the state in Activity lifecycle methods like `onPause`.

So, instead of extending `WebView` and overriding blah, blah, blah..., I use a Handler and post model.

private final Handler mHandler = new Handler();
// in onCreate
mHandler.postDelayed(new Runnable() {

                @Override
                public void run() {
                    if (mWebView.getContentHeight() > 0) {
                        mWebView.scrollTo(0, mLastPosition);
                        Log.d("scrolling", "true");
                        mHandler.removeCallbacks(this);
                    } else {
                        mHandler.postDelayed(this, 100);
                    }
                }
            }, 100);

This code block will peridically check if the WebView page can be manipulated, if so, it does the scrolling and remove the callback, otherwise it loops. I test this and find out it ususally won't take very long.

Hope this helps!

查看更多
别忘想泡老子
4楼-- · 2019-01-03 10:02

This is not a direct answer for the question asked, but you can alternatively use the WebChromeClient. I find it to me more reliable and I have it configured to display loading progress. I was having the same issue with WebView hiding the ProgressBar before the page was fully loaded and I replaced WebView with WebView client.

I use the following code

final WebView wvMax = (WebView) findViewById(R.id.webViewTnSmax);
final ProgressBar pbMax = (ProgressBar) findViewById(R.id.progressBarTnSmax);

wvMax.setWebChromeClient(new WebChromeClient() {
    public void onProgressChanged(WebView view, int progress) {
        pbMax.setVisibility(View.VISIBLE);
        pbMax.setProgress(progress);
        if (progress == 100) {
            pbMax.setVisibility(View.GONE); // Make the bar disappear after URL is loaded
        }
    }

    public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {
        // do something
    }
});
查看更多
干净又极端
5楼-- · 2019-01-03 10:06

EDIT: Since I first posted this, this method has been deprecated in Android API 12. Thanks, Google! I will leave the original answer in tact:


Yes-- there IS a listener for knowing when the content has finished loading. I had to create one on my project so I could do a splash screen which stayed up until the webview had loaded the page.

It's called .setPictureListener.

For example:

mWebView.setPictureListener(new MyPictureListener());
//... and then later on....
class MyPictureListener implements PictureListener {

    @Override
    public void onNewPicture(WebView view, Picture arg1) {
      // put code here that needs to run when the page has finished loading and
      // a new "picture" is on the webview.      
    }    
} 
查看更多
Juvenile、少年°
6楼-- · 2019-01-03 10:11

Its working fine on all devices :- Load Web View ProgressDialog

查看更多
登录 后发表回答