Android WebView报告内容高度不正确



我正在使用应该加载网页的Android应用程序,如果内容高度大于视图高度,请滚动内容。

问题是,在几页上,即使我可以手动向下滚动,WebView.getContentHeight()似乎也返回视图的确切高度。这意味着我没有适合动画师的正确值,并且滚动无法正常工作。

当前,要测试问题,我将滚动更改侦听器设置为记录WebView滚动到末尾的消息。

        webView.setOnScrollChangeListener(new View.OnScrollChangeListener() {
        @Override
        public void onScrollChange(View view, int i, int i1, int i2, int i3) {
            Log.d(TAG, String.format("scrollX: %d, scrollY: %d, oldScrollX: %d, oldScrollY: %d", i, i1, i2, i3));
            int height = (int) Math.floor(webView.getContentHeight() * webView.getScaleY());
            if (webView.getScrollY() + webView.getHeight() >= height && progress > 99)
                Log.d(TAG, "Reached bottom: " + height);
        }
    });

日志显示的缩放内容高度为1586,Web视图高度为1586。但是,我可以手动向下滚动页面,然后获得此日志输出:

WebPageView: scrollX: 0, scrollY: 1960, oldScrollX: 0, oldScrollY: 1774
WebPageView: Reached bottom: 1773
WebPageView: scrollX: 0, scrollY: 1959, oldScrollX: 0, oldScrollY: 1960
WebPageView: Reached bottom: 1773

对我来说,这清楚地表明内容高度被误报,如:

WebView.getScrollY() + WebView.getHeight() > WebView.getContentHeight() * WebView.getScaleY()

我也设置了一个WebChromeClient,并且过载了onProgressChanged(),我知道在检索内容高度时,页面已完成。

什么可能导致 WebView误报出内容高度,因为它确实更大?

编辑:我已经在Android 6.0、7.0和7.1上运行该应用程序。build.gradle中的minsdkversion是23,而targetsdkversion为25。网络浏览版本为44.0.2403.119。

更新:正如注释中指出的那样,computeVerticalScrollRange()是一种受保护的方法,因此您必须进行子类WebView以使此方法起作用。这可以通过将侦听器放入子类中或创建登录方法来返回受保护方法的值来实现。


而不是使用getContentHeight(),请尝试使用computeVerticalScrollRange()

滚动值表示为任意单元,但是在返回或使用滚动值的所有不同方法中它们都一致。因此,尽管内容高度可能以像素为单位,但滚动单元却不是。您需要更新您的代码,以便准确地检测到滚动。

在Java中:

webView.setOnScrollChangeListener(new View.OnScrollChangeListener() {
    @Override
    public void onScrollChange(View view, int i, int i1, int i2, int i3) {
        int maxScrollRange = computeVerticalScrollRange();
        if (webView.getScrollY() + webView.getMeasuredHeight() >= maxScrollRange) {
            Log.d(TAG, "Reached the bottom.");
        }
    }
});

或Kotlin:

webView.setOnScrollChangeListener { _,_,_,_,_ ->
    val maxScrollRange = computeVerticalScrollRange()
    if(webView.scrollY + webView.measuredHeight >= maxScrollRange) {
        Log.d(TAG, "Reached the bottom.")
    }
}

最新更新