当前位置:  开发笔记 > 编程语言 > 正文

当WebView显示内容时是否有监听器?

如何解决《当WebView显示内容时是否有监听器?》经验,为你挑选了4个好方法。

使用WebViewClient和/或WebChromeClient,您可以在页面加载时获取侦听器,但是在WebView显示任何内容之前,有时会在WebView中包含任何内容之前调用它.

什么是确定WebView何时显示其内容的有效方法?

编辑:(试图更清楚)

当我在WebView中加载页面时,我想将滚动设置为特定位置.看起来在页面加载之前无法设置滚动位置,并且它具有实际的内容高度.因此,我尝试了两种不同的方法来确定页面何时完成加载,来自WebViewClient的onPageFinished()以及来自WebChromeClient的onProgressChanged().这两个都告诉我页面何时完成加载.

但问题是,有时在页面显示之前调用它,因此页面没有高度,滚动调用什么都不做.

我试图找到一种可靠的方法来确定页面何时可以滚动,即.当它的内容高度.

我想我可以在完成加载后设置一个检查循环,以便在高度可用时继续寻找,但这看起来很像黑客.希望有一种更清洁的方式.



1> cottonBallPa..:

我用PictureListener成功地使用了Richard的答案几年,但我不再推荐这个作为最佳解决方案.

这有两个原因:

    webView.setPictureListener和PictureListener都弃用.

    使用此侦听器将导致WebView经常分配新图片.这种分配很昂贵,这可能会对性能产生一些重大影响甚至导致JellyBean MR1上的本机崩溃.

相反,我建议创建WebView的子类并覆盖invalidate(),如下所示:

@Override
public void invalidate() {
    super.invalidate();

    if (getContentHeight() > 0) {
        // WebView has displayed some content and is scrollable.
    }
}

如果您仍想使用PictureListener方法,那么在完成后将setPictureListener恢复为null将获得更好的性能.


这是我找到的最佳解决方案.但是,在某些情况下,当WebView中的WebView内容更新时,不会调用invalidate().一个不寻常的情况是,当调用loadDataWithBaseURL时,前一个内容位于顶部,因此我在调用loadDataWithBaseURL后还添加了一个对invalidate的延迟调用.
确实是最好的解决方案 添加`getProgress()== 100`帮助我确保内容完全呈现.

2> Richard..:

编辑:自从我第一次发布此功能以来,此方法已在Android API 12中弃用.谢谢,Google!我会留下原始答案:


是的 - 有一个听众知道内容何时完成加载.我不得不在我的项目中创建一个,所以我可以做一个启动画面,直到webview加载页面为止.

它被称为.setPictureListener.

例如:

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.      
    }    
} 


真棒.这完全符合我的预期.使用此功能的其他人的警告......当你在页面中移动时,它确实经常被调用,因此请确保onNewPicture方法中发生的任何事情都很快.
不,我错了.WebKit文档所指的"图片"是浏览器内容的呈现.我最初很困惑为什么上面的技术不适合我,因为除非渲染*实际出现在屏幕*上,否则事件不会被触发.

3> Paul Lammert..:

这里建议的解决方案充其量只是hacky,而有一个非常干净的解决方案,根据Android文档:

WebViewClient client = new WebViewClient() {
    @Override
    public void onPageFinished(WebView view, String url) {
        Log.d("MYAPP", "Page loaded");
    }
};
webView.setWebViewClient(client);


我希望这就是答案,但根据我的经验,在内容显示/可滚动/可测量之前,我可以在很长一段时间内调用PageFinished.因此,如果您尝试在onPageFinished方法中滚动,则内容高度可能仍为0.

4> user3103871..:

我读了这个讨论,我也遇到了同样的问题.

我搜索了很多,但他们不是他们承诺的解决方案.

而且我不想使用已弃用的`onNewPicture`回调.

在我自己的情况下,我只需要在活动开始时恢复`WebView`滚动位置,我认为这是大多数情况,因为当活动任务堆栈进入后台时,Android会自动保存`WebView`状态,所以当它弹出到前台,看起来会一样.如果它在后台被杀死,我相信你会设法将状态保存在像`onPause`这样的Activity生命周期方法中.

所以,我没有扩展`WebView`而是覆盖blah,blah,blah ......,而是使用Handler和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);

此代码块将进行peridically检查是否可以操作WebView页面,如果是,它会进行滚动并删除回调,否则循环.我测试了这个并且发现它通常不会花很长时间.

希望这可以帮助!

推荐阅读
和谐啄木鸟
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有