在这之前,我们知道Android对Touch事件的分发是有自己一套机制的。主要是有是三个函数:
dispatchTouchEvent、onInterceptTouchEvent和onTouchEvent。
这种分发机制有一个漏洞:
如果子view获得处理touch事件机会的时候,父view就再也没有机会去处理这个touch事件了,直到下一次手指再按下。
事件分发是这样的:子View首先得到事件处理权,处理过程中,父View可以对其拦截,但是拦截了以后就无法再还给子View(本次手势内)。
NestedScrolling机制是这样的:内部View在滚动的时候,首先将dx,dy交给NestedScrollingParent,NestedScrollingParent可对其进行部分消耗,剩余的部分还给内部View。
NestedScrolling机制主要和NestedScrollingParent有关,看源码:
public class NestedScrollView extends FrameLayout implements NestedScrollingParent,
NestedScrollingChild, ScrollingView {
NestedScrolling实现了NestedScrollingParent,NestedScrollingChild,ScrollingView 接口。
那么NestedScrollingParent,NestedScrollingChild是什么?
NestedScrollingParent
public interface NestedScrollingParent {
// 参数child:ViewParent包含触发嵌套滚动的view的对象
// 参数target:触发嵌套滚动的view (在这里如果不涉及多层嵌套的话,child和target)是相同的
// 参数nestedScrollAxes:就是嵌套滚动的滚动方向了.
public boolean onStartNestedScroll(View child, View target, int nestedScrollAxes);
public void onNestedScrollAccepted(View child, View target, int nestedScrollAxes);
public void onStopNestedScroll(View target);
// 参数target:同上
// 参数dxConsumed:表示target已经消费的x方向的距离
// 参数dyConsumed:表示target已经消费的x方向的距离
// 参数dxUnconsumed:表示x方向剩下的滑动距离
// 参数dyUnconsumed:表示y方向剩下的滑动距离
public void onNestedScroll(View target, int dxConsumed, int dyConsumed,
int dxUnconsumed, int dyUnconsumed);
// 参数dx:表示target本次滚动产生的x方向的滚动总距离
// 参数dy:表示target本次滚动产生的y方向的滚动总距离
// 参数consumed:表示父布局要消费的滚动距离,consumed[0]和consumed[1]分别表示父布局在x和y方向上消费的距离.
public void onNestedPreScroll(View target, int dx, int dy, int[] consumed);
public boolean onNestedFling(View target, float velocityX, float velocityY, boolean consumed);
public boolean onNestedPreFling(View target, float velocityX, float velocityY);
public int getNestedScrollAxes();
}
1,onStartNestedScroll.当子view的调用NestedScrollingChild的方法startNestedScroll时,会调用该方法.
2,onNestedScrollAccepted.如果onStartNestedScroll方法返回的是true的话,那么紧接着就会调用该方法.它是让嵌套滚动在开始滚动之前,让布局容器(viewGroup)或者它的父类执行一些配置的初始化的.下面是原文:
(It offers an opportunity for the view and its superclasses to perform initial configuration for the nested scroll.)
3,onStopNestedScroll停止滚动了,当子view调用stopNestedScroll时会调用该方法.
4,onNestedScroll,当子view调用dispatchNestedScroll方法时,会调用该方法.
5,onNestedPreScroll,当子view调用dispatchNestedPreScroll方法是,会调用该方法.
6,dispatchNestedFling和dispatchNestedPreFling对应的就是滑动了.
onStartNestedScroll该方法,一定要按照自己的需求返回true,该方法决定了当前控件是否能接收到其内部View(非并非是直接子View)滑动时的参数;假设你只涉及到纵向滑动,这里可以根据nestedScrollAxes这个参数,
进行纵向判断。
onNestedPreScroll该方法的会传入内部View移动的dx,dy