NestedScrollWebview实现与优化

NestedScrollWebview实现与优化

说明: 本文系转载, 原文地址: http://blog.csdn.net/m5314/article/details/68943869

原文如下: 
好久没写了,好像也没什么人关注我,呵呵,但我还是坚持写一下,希望能帮到有需要的人! 
今天我来说一下NestedScrollWebview。

最近在弄一个需求,我需要用到coordinatorlayout + webview 实现滚动交互效果,但要实现该效果子view必须是要实现NestedScrollingChild接口的,很可惜原生webview并没有实现这接口。 
网上找到能实现这种需求的有两种方法: 
1)NestedScrollView 嵌套 webview 
这种方法我试过,确实可以达到效果,但有一个比较坑的问题。就是webview的高度变成网页高度,导致网页滚动事件的缺失,如果网页需要监听滚动事件实现某些效果时(如图片懒加载)这时就会失效。

2)NestedScrollWebview 
google官方并没有提供这个控件,网上能找到的就是rhlff大神写的一个控件(https://github.com/rhlff/NestedScrollWebView),我也用了这个控件,但实际效果比较差,滚动时网页会抖动。

为了实现需求,只能改大神的代码了,看了一轮大神的代码后我修改了事件分发时的逻辑,实测效果跟上述第一种方法效果相似且没有副作用,详细代码如下:

public class NestedScrollWebView extends WebView implements NestedScrollingChild {  

    public static final String TAG = NestedScrollWebView.class.getSimpleName();  

    private int mLastMotionY;  

    private final int[] mScrollOffset = new int[2];  
    private final int[] mScrollConsumed = new int[2];  

    private int mNestedYOffset;  

    private NestedScrollingChildHelper mChildHelper;  

    public NestedScrollWebView(Context context) {  
        super(context);  
        init();  
    }  

    public NestedScrollWebView(Context context, AttributeSet attrs) {  
        super(context, attrs);  
        init();  
    }  

    public NestedScrollWebView(Context context, AttributeSet attrs, int defStyleAttr) {  
        super(context, attrs, defStyleAttr);  
        init();  
    }  

    private void init() {  
        mChildHelper = new NestedScrollingChildHelper(this);  
        setNestedScrollingEnabled(true);  
    }  

    @Override  
    public boolean onTouchEvent(MotionEvent event) {  
        boolean result = false;  

        MotionEvent trackedEvent = MotionEvent.obtain(event);  

        final int action = MotionEventCompat.getActionMasked(event);  

        if (action == MotionEvent.ACTION_DOWN) {  
            mNestedYOffset = 0;  
        }  

        int y = (int) event.getY();  

        event.offsetLocation(0, mNestedYOffset);  

        switch (action) {  
            case MotionEvent.ACTION_DOWN:  
                mLastMotionY = y;  
                startNestedScroll(ViewCompat.SCROLL_AXIS_VERTICAL);  
                result = super.onTouchEvent(event);  
                break;  
            case MotionEvent.ACTION_MOVE:  
                int deltaY = mLastMotionY - y;  

                if (dispatchNestedPreScroll(0, deltaY, mScrollConsumed, mScrollOffset)) {  
                    deltaY -= mScrollConsumed[1];  
                    trackedEvent.offsetLocation(0, mScrollOffset[1]);  
                    mNestedYOffset += mScrollOffset[1];  
                }  

                int oldY = getScrollY();  
                mLastMotionY = y - mScrollOffset[1];  
                int newScrollY = Math.max(0, oldY + deltaY);  
                deltaY -= newScrollY - oldY;  
                if (dispatchNestedScroll(0, newScrollY - deltaY, 0, deltaY, mScrollOffset)) {  
                    mLastMotionY -= mScrollOffset[1];  
                    trackedEvent.offsetLocation(0, mScrollOffset[1]);  
                    mNestedYOffset += mScrollOffset[1];  
                }  
                if(mScrollConsumed[1]==0 && mScrollOffset[1]==0) {  
                    trackedEvent.recycle();  
                    result = super.onTouchEvent(trackedEvent);  
                }  
                break;  
            case MotionEvent.ACTION_POINTER_DOWN:  
            case MotionEvent.ACTION_UP:  
            case MotionEvent.ACTION_CANCEL:  
                stopNestedScroll();  
                result = super.onTouchEvent(event);  
                break;  
        }  
        return result;  
    }  

    // NestedScrollingChild  

    @Override  
    public void setNestedScrollingEnabled(boolean enabled) {  
        mChildHelper.setNestedScrollingEnabled(enabled);  
    }  

    @Override  
    public boolean isNestedScrollingEnabled() {  
        return mChildHelper.isNestedScrollingEnabled();  
    }  

    @Override  
    public boolean startNestedScroll(int axes) {  
        return mChildHelper.startNestedScroll(axes);  
    }  

    @Override  
    public void stopNestedScroll() {  
        mChildHelper.stopNestedScroll();  
    }  

    @Override  
    public boolean hasNestedScrollingParent() {  
        return mChildHelper.hasNestedScrollingParent();  
    }  

    @Override  
    public boolean dispatchNestedScroll(int dxConsumed, int dyConsumed, int dxUnconsumed, int dyUnconsumed, int[] offsetInWindow) {  
        return mChildHelper.dispatchNestedScroll(dxConsumed, dyConsumed, dxUnconsumed, dyUnconsumed, offsetInWindow);  
    }  

    @Override  
    public boolean dispatchNestedPreScroll(int dx, int dy, int[] consumed, int[] offsetInWindow) {  
        return mChildHelper.dispatchNestedPreScroll(dx, dy, consumed, offsetInWindow);  
    }  

    @Override  
    public boolean dispatchNestedFling(float velocityX, float velocityY, boolean consumed) {  
        return mChildHelper.dispatchNestedFling(velocityX, velocityY, consumed);  
    }  

    @Override  
    public boolean dispatchNestedPreFling(float velocityX, float velocityY) {  
        return mChildHelper.dispatchNestedPreFling(velocityX, velocityY);  
    }  

}  
  • 4
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值