如何在android中检测webview的scrollend?

时间:2014-01-08 14:14:51

标签: android webview

我是一个原生应用,如果用户滚动到webview的末尾,我想显示/隐藏按钮。我查看了一个答案here,并了解了如何通过接口注册回调。我的主要问题是我无法在onScrollChanged方法中进行计算。我尝试过getHeight(),getContentHeight(),top等组合,但它似乎太早了。我尝试使用像谷歌这样的简单页面,内容相对较少,也有新闻页面。

这些逻辑适用于普通滚动视图。由于网页内容很多,可能会搞乱计算。粘贴示例代码:不起作用。

@Override
protected void onScrollChanged(int left, int top, int oldLeft, int oldTop) {
    if ( mOnWebViewBottomReachedListener != null ) {
        //if ( (getContentHeight() - (top + getHeight())) <= mMinDistance )
        int diff = (getBottom() - (getHeight() + getScrollY()));
        Log.e("values ", diff+" o");
        if ((int) Math.floor(getContentHeight() * getScaleY()) == top)
            mOnWebViewBottomReachedListener.onBottomReached(this);
    }
    super.onScrollChanged(left, top, oldLeft, oldTop);
}

需要帮助。感谢。

5 个答案:

答案 0 :(得分:10)

@Override
protected void onScrollChanged(int l, int t, int oldl, int oldt) {
    int height = (int) Math.floor(this.getContentHeight() * this.getScale());  
    int webViewHeight = this.getMeasuredHeight();  
    if(this.getScrollY() + webViewHeight >= height){  
       Log.i("THE END", "reached");
    }
    super.onScrollChanged(l, t, oldl, oldt);
}

此逻辑适用于webview。

答案 1 :(得分:4)

首先从此课程扩展您的网页视图。 https://stackoverflow.com/a/14753235/3027225 在此次升级之后,您的webView就像这样

 <com.YourPackageName.ObservableWebView
            android:id="@+id/webView"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentBottom="true"
            android:layout_alignParentLeft="true"
            android:layout_alignParentRight="true" />

最后覆盖onScroll方法,如下所示:

webView.setOnScrollChangedCallback(new OnScrollChangedCallback() {

            @Override
            public void onScroll(int l, int t) {
                  int tek = (int) Math.floor(webView.getContentHeight() * webView.getScale());
                  if(tek - webView.getScrollY() == webView.getHeight())
                     Toast.makeText(getActivity(), "End", Toast.LENGTH_SHORT).show();


            }
        });

答案 2 :(得分:3)

经过大量的谷歌搜索后,我找到的所有解决方案都在计算高度并确定scrollOfset,但大多数解决方案在大多数情况下都不可靠,导致此处描述的问题Weird miscalculation when trying to detect if WebView scrolled to bottom

我发现100%有效的解决方案是根据overScroll确定它

webView.setOnOverScrolledCallback(new WebViewCustom.OnOverScrolledCallback() {
                @Override
                public void onOverScrolled(int scrollX, int scrollY, boolean clampedX, boolean clampedY) {
                    if(clampedY)
                        if(scrollY == 0) {
                            //top
                        }
                        else {
                            //bottom
                        }

                }
            });

答案 3 :(得分:1)

这三种方法组合对我来说非常好

  
      
  1. 创建两个布尔变量,两个检测topReached或bottomReached。

  2.   
  3. 使用computeVerticalScrollRange()获取垂直滚动范围。   当内容高度较小时,computeVerticalScrollRange()将帮助您(在这种情况下onScrollChanged未被调用)。

  4.   
  5. 使用onScrollChanged来检测滚动是否正在讨价还价。   滚动表示内容高度大于webView测量的高度。现在使用newt检测底端或使用newt检测顶部。
  6.   
private boolean topReached = false, bottomReached = false;

 @Override
protected int computeVerticalScrollRange() {

    int readerViewHeight = getMeasuredHeight();

    int verticalScrollRange = super.computeVerticalScrollRange();


    if (readerViewHeight >= verticalScrollRange) {

        topReached = true;

        bottomReached = true;

    }

    return verticalScrollRange;
}

@Override
protected void onScrollChanged(int newLeft, int newTop, int oldLeft, int oldTop) {

    Logger.i(TAG, "onScrollChanged");

    topReached = false;

    bottomReached = false;

    Log.i(TAG, "onScrollChanged newLeft : " + newLeft);
    Log.i(TAG, "onScrollChanged newTop : " + newTop);
    Log.i(TAG, "onScrollChanged oldLeft : " + oldLeft);
    Log.i(TAG, "onScrollChanged oldTop : " + oldTop);

    int readerViewHeight = getMeasuredHeight();

    int contentHeight = getContentHeight();

    if (newTop == 0) {

        Log.d(TAG, "onScrollChanged : Top End");

        topReached = true;

    } else if (newTop + readerViewHeight >= contentHeight) {

        Log.d(TAG, "onScrollChanged : Bottom End");

        bottomReached = true;

    }

    super.onScrollChanged(newLeft, newTop, oldLeft, oldTop);

}

答案 4 :(得分:0)

在 android 版本 8-11 上检查过这个。它工作 100%。我通过使用 computeVerticalScrollRangecomputeVerticalScrollExtent 实现了它。以下是活动/片段中的 webview 示例。

创建自定义 webview 类。

public class MyWebView extends WebView {
    public MyWebView(Context context) {
        super(context);
    }

    public MyWebView(@NonNull Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    public int computeVerticalScrollRange() {
        return super.computeVerticalScrollRange();
    }

    @Override
    protected int computeVerticalScrollExtent() {
        return super.computeVerticalScrollExtent();
    }
}

在您的布局文件中,像这样实现 webview 并根据需要将此布局文件包含到您的 activityfragment 视图文件中。

 <in.package.folder.MyWebView
        android:id="@+id/webview"
        android:layout_width="match_parent"
        android:layout_height="0dp"/>

在您想要拥有网络视图的活动/片段中

  1. 声明变量
private MyWebView webView;
  1. 找到元素id并初始化webView
 webView = (MyWebView) findViewById(R.id.webview);
  1. 使用 computeVerticalScrollRange 类中定义的 computeVerticalScrollExtentwebview 方法计算滚动结束。如果滚动已到达 webview 内容的末尾,则第三个参数 i1 ( Scroll Y) 将等于 (computeVerticalScrollRange - computeVerticalScrollExtent)
 webView.setOnScrollChangeListener((view, i, i1, i2, i3) -> {
            int r1 = webView.computeVerticalScrollRange();
            int r2 = webView.computeVerticalScrollExtent();
            if (i1 == (r1 - r2)) {
                "REACHED END OF THE SCROLL"
            } 
        });