NestedScrollChild与NestedScrollParent的认识

来源:互联网 发布:linux 应用层驱动 编辑:程序博客网 时间:2024/06/05 14:53

之前给大家写过一篇文章是关于NestedScrollParent的,只能算是初步的介绍了,当然,也给本篇文章作了一个开头。前面那边文章讲述了,NestedScrolllParent跟RecyclerView的结合,由于,RecyclerView帮我们实现了NestedScrollChild的方法,所以,我们并不能够完全的理解这两者的用法,所以,这篇文章就是要告诉大家NestedScrollParent 跟NestedScrollChild如何能够完美使用,使你需要的效果更容易实现。

主要分为三块,顶部、中间titlebar、还有就是ScrollView了,先上个截图了。


这里了,要实现的效果就是先整体滑动,当顶部隐藏的时候,中间的titlebar部分悬停,下面的ScrollView开始滚动,当下拉的时候,先滑动ScrollView部分,当顶部出现的时候,这个时候就交给Parent来处理滑动事件了。

好了,先介绍下NestedScrollParent的实现吧。之前介绍过一些方法,这里就不一一介绍了,主要讲解主要逻辑代码。

先上代码了!

 @Override    public void onNestedPreScroll(View target, int dx, int dy, int[] consumed) {        Log.e(TAG, "onNestedPreScroll");        super.onNestedPreScroll(target, dx, dy, consumed);        boolean hiddenTop=dy>0 && getScrollY() <topviewHeight;         boolean showTop=dy<0 && getScrollY()>=0 && !ViewCompat.canScrollVertically(target,-1);        if(hiddenTop||showTop){            scrollBy(0,dy);            consumed[1]=dy; //消耗y轴滑动事件        }    }
这里,主要是先拿到在什么情况下Parent处理事件,什么情况下Child处理事件。在这里呢,分两种情况。向上滑动的时候,dy>0并且滑动的距离小于topHeight的时候,是Parent处理事件,反之,则是child处理事件;第二种情况是向下滑动的时候,dy<0并且滑动距离是大于0的,然后就是消耗y轴的事件了consumed[1]=dy。

 @Override    public void scrollTo(int x, int y) {        if(y<0){            y=0;        }        if(y>topviewHeight){            y=topviewHeight;        }        if(y!=getScrollY()){            super.scrollTo(x, y);        }    }    @Override    public void computeScroll() {        super.computeScroll();        if(mScroller.computeScrollOffset()){            scrollTo(0,mScroller.getCurrY());            invalidate();        }    }

这块部分主要是处理快速滑动时候的逻辑。

然后就是分析NestedScrollChild了。这个接口的代码完全可以通过NestedScrollingChildHelper这个类来解决。这个类主要就是为了解决父View跟子View的滑动冲突的。直接上代码

public class ScrollChild extends ScrollView implements NestedScrollingChild{    private NestedScrollingChildHelper childHelper;    private int [] consumed=new int[2];    private int [] offsetInWindow=new int[2];    private int downX;    private int downY;    private VelocityTracker mVelocityTracker=null;    private boolean allowFly=false;    public ScrollChild(Context context) {        super(context);    }    public ScrollChild(Context context, AttributeSet attrs) {        super(context, attrs);        childHelper=new NestedScrollingChildHelper(this);        setNestedScrollingEnabled(true);    }    @Override    public boolean onTouchEvent(MotionEvent ev) {        if(mVelocityTracker==null){            mVelocityTracker=VelocityTracker.obtain();        }        mVelocityTracker.addMovement(ev);        switch (ev.getAction()){            case MotionEvent.ACTION_DOWN:                allowFly=false;                downX= (int) ev.getRawX();                downY= (int) ev.getRawY();                startNestedScroll(ViewCompat.SCROLL_AXIS_HORIZONTAL|ViewCompat.SCROLL_AXIS_VERTICAL);                break;            case MotionEvent.ACTION_MOVE:                int moveX= (int) ev.getRawX();                int moveY= (int) ev.getRawY();                int dx=moveX-downX;                int dy=-(moveY-downY);                downY=moveY;                downX=moveX;                if(dispatchNestedPreScroll(0,dy,consumed,offsetInWindow)){                    dy=consumed[1];                    ScrollChild.this.scrollBy(0,dy);                    allowFly=true;                }                break;            case MotionEvent.ACTION_UP:                stopNestedScroll();                if(allowFly){                    mVelocityTracker.computeCurrentVelocity(1000);                    int mScrollFly= (int) mVelocityTracker.getYVelocity();                    fling(-mScrollFly);                }                break;        }        return super.onTouchEvent(ev);    }    @Override    public void stopNestedScroll() {        childHelper.stopNestedScroll();    }    @Override    public boolean dispatchNestedPreScroll(int dx, int dy, int[] consumed, int[] offsetInWindow) {        return childHelper.dispatchNestedPreScroll(dx, dy, consumed, offsetInWindow);    }    @Override    public boolean startNestedScroll(int axes) {        return childHelper.startNestedScroll(axes);    }    @Override    public void setNestedScrollingEnabled(boolean enabled) {        childHelper.setNestedScrollingEnabled(enabled);    }}

ok,最后依旧是送上demo 点击打开链接




1 0
原创粉丝点击