美文网首页
canScrollVertically和scrollBy的使用问

canScrollVertically和scrollBy的使用问

作者: 仰望天空的小鸟 | 来源:发表于2018-04-17 11:09 被阅读0次

    最近项目使用CoordinatorLayout + Webview实现文章详情页上拉折叠头部效果,由于Webview并不支持app:layout_behavior,于是在Webview外套了一层NestScrollView, 由NestScrollView支持app:layout_behavior,然后重写NestScrollView的dispatchNestedScroll来控制Wevview的滚动,一开始的实现是

    ```

    val canScroll =mWebView.canScrollVertically(dy)

    if (canScroll) {

        ...

        mWebView.scrollBy(dxUnconsumed, dy)

        ...

        return true

    }

    ```

    然后发现往上滚时,mWebView顶部的一些内容滚不下来了,而且canScrollVertically返回false

    后来通过一番研究,发现这是View的一个坑(也算是View的一个bug)

    View内部有个变量mScrollY记录当前滚动距离,当scrollBy(dxUnconsumed, dy)中的dy+mScrollY < 0 时,scrollBy不会进行任何实际滚动,但同时它却会把mScrollY设为为dy+mScrollY

    这就导致之后怎么滚都滚不下来(此时dy < 0)

    因为canScrollVertically()的实现是:

    ```

    public boolean canScrollVertically(int direction) {

    final int offset = computeVerticalScrollOffset();

        final int range = computeVerticalScrollRange() - computeVerticalScrollExtent();

        if (range ==0)return false;

        if (direction <0) {

    return offset >0;

        }else {

    return offset < range -1;

        }

    }

    protected int computeVerticalScrollOffset() {

    return mScrollY;

    }

    ```

    当最后一次滚动的dy < -mScrollY 时, mScrollY = dy+mScrollY, mScrollY变为负数,导致之后的往上滚时canScrollVertically都是返回false。

    问题解决的方法是实现dispatchNestedScroll改为以下代码

    ```

    val canScroll =mWebView.canScrollVertically(dy)

    if (canScroll) {

        ...

        if (dy < 0) {

            dy = -min(-dy, mWebView.computeVerticalScrollOffset())

            mWebView.view.scrollBy(dxUnconsumed, dy)

            return true

        }

        ...

        return true

    }

    ```

    相关文章

      网友评论

          本文标题:canScrollVertically和scrollBy的使用问

          本文链接:https://www.haomeiwen.com/subject/jrmwaxtx.html