嵌套滚动实现接口
- NestedScrollingChild.java
简洁版
package android.support.v4.view;
import android.support.annotation.Nullable;
import android.support.v4.view.ViewCompat.ScrollAxis;
import android.view.MotionEvent;
import android.view.VelocityTracker;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.ViewParent;
public interface NestedScrollingChild {
void setNestedScrollingEnabled(boolean enabled);
boolean isNestedScrollingEnabled();
boolean startNestedScroll(@ScrollAxis int axes);
void stopNestedScroll();
boolean hasNestedScrollingParent();
boolean dispatchNestedScroll(int dxConsumed, int dyConsumed,int dxUnconsumed, int dyUnconsumed, @Nullable int[] offsetInWindow);
boolean dispatchNestedPreScroll(int dx, int dy, @Nullable int[] consumed,@Nullable int[] offsetInWindow);
boolean dispatchNestedFling(float velocityX, float velocityY, boolean consumed);
boolean dispatchNestedPreFling(float velocityX, float velocityY);
}
复制代码
复杂版
package android.support.v4.view;
import android.support.annotation.Nullable;
import android.support.v4.view.ViewCompat.ScrollAxis;
import android.view.MotionEvent;
import android.view.VelocityTracker;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.ViewParent;
public interface NestedScrollingChild {
//为这个视图启用或禁用嵌套滚动
如果该属性设置为true,视图将被允许使用当前层次结构中的兼容父视图启动嵌套滚动操作。如果该视图没有实现嵌套滚动,则没有效果。在执行嵌套滚动时禁用嵌套滚动会停止嵌套滚动。
void setNestedScrollingEnabled(boolean enabled);
//如果此视图启用了嵌套滚动,则返回true。
如果启用了嵌套滚动,并且这个视图类实现支持它,那么这个视图将作为一个嵌套滚动子视图(在适用的情况下),将有关滚动操作的数据转发给兼容的、协作的嵌套滚动父视图。
boolean isNestedScrollingEnabled();
//沿着给定的轴开始一个新的滚动操作。
开始嵌套滚动条的视图承诺遵守以下约定:
在启动滚动操作时,视图将调用startNestedScroll。在触摸滚动的情况下,这对应于初始的ACTION_DOWN。在触摸滚动的情况下,嵌套滚动将以与requestDisallowInterceptTouchEvent(boolean)相同的方式自动终止。在程序滚动的情况下,调用者必须显式调用stopNestedScroll()来指示嵌套滚动的结束。
如果startNestedScroll返回true,就找到了合作的父母。如果返回false,调用者可能会在下次滚动之前忽略该契约的其余部分。当嵌套的滚动已经在进行时调用startNestedScroll,将返回true。
在滚动的每一个增量步骤中,调用者应该在计算了请求的滚动增量之后调用dispatchNestedPreScroll。如果返回true,嵌套的滚动父控件至少会部分地使用滚动条,调用方应该调整滚动条的数量。
在应用了滚动三角洲的其余部分之后,调用者应该调用dispatchNestedScroll,将消耗的和未消耗的都传递出去。嵌套的滚动父控件可能会以不同的方式处理这些值。查看onNestedScroll(View, int, int, int, int)。
boolean startNestedScroll(@ScrollAxis int axes);
//停止正在进行的嵌套滚动。
当嵌套滚动块当前没有进行时调用此方法是无害的。
void stopNestedScroll();
//如果该视图有嵌套的滚动父视图,则返回true。
嵌套滚动父视图的存在表明该视图已经启动了嵌套滚动,并且它被位于视图层次结构上的祖先视图所接受。
boolean hasNestedScrollingParent();
//分派正在进行的嵌套滚动的一个步骤。
支持嵌套滚动的视图的实现应该调用这个函数,以便向当前嵌套滚动的父视图报告正在进行中的滚动的信息。如果嵌套滚动条当前没有运行,或者此视图未启用嵌套滚动条,则此方法不会执行任何操作。
兼容的视图实现还应该在使用滚动事件本身的组件之前调用dispatchNestedPreScroll。
boolean dispatchNestedScroll(int dxConsumed, int dyConsumed,
int dxUnconsumed, int dyUnconsumed, @Nullable int[] offsetInWindow);
//在这个视图使用它的任何部分之前,分派正在进行中的嵌套滚动的一个步骤
嵌套预滚动事件就是嵌套滚动事件,触摸拦截就是触摸。dispatchNestedPreScroll可以让嵌套滚动操作中的父视图在子视图使用滚动之前,使用部分或全部滚动操作。
boolean dispatchNestedPreScroll(int dx, int dy, @Nullable int[] consumed,
@Nullable int[] offsetInWindow);
//向嵌套的滚动父控件发送一个猛击。
此方法应用于指示嵌套滚动子节点已检测到适当的触发条件。一般来说,这意味着触控滚动结束时,滚动方向的速度达到或超过可滚动轴上的最小抛速。
如果嵌套的滚动子视图通常会引发弹出,但它位于其自身内容的边缘,则可以使用此方法将引发的弹出委托给嵌套的滚动父视图。父母可以随意消费或观察孩子的放纵行为。
boolean dispatchNestedFling(float velocityX, float velocityY, boolean consumed);
//在此视图处理嵌套的滚动父视图之前,将抛出操作分派给它。
嵌套的预滚动事件是嵌套的预滚动事件,触摸拦截是触摸,嵌套的预滚动是嵌套滚动。dispatchNestedPreFling为嵌套的父视图提供了一个机会,可以在子视图使用抛投之前完全使用抛投。如果这个方法返回true,一个嵌套的父视图就会使用fling,因此这个视图不会滚动。
为了获得更好的用户体验,在嵌套的滚动链中,每次只应该使用一个视图。如果父视图使用了fling这个方法将返回false。自定义视图实现应该以两种方式说明这一点:
如果自定义视图被分页,并且需要固定的分页点,不要调用dispatchNestedPreFling;不管怎样,消耗抛掷和安定到一个有效的位置。
如果嵌套的父节点确实使用了fling,那么这个视图根本就不应该滚动,甚至可以返回到一个有效的空闲位置。
视图也不应该提供沿当前不支持滚动的轴的嵌套父视图的投掷速度;滚动视图不应该向其父视图提供水平的抛速,因为不允许沿该轴滚动,并且沿该运动携带速度没有意义。
boolean dispatchNestedPreFling(float velocityX, float velocityY);
}
复制代码
- NestedScrollingParent.java
简洁版
package android.support.v4.view;
import android.support.annotation.NonNull;
import android.support.v4.view.ViewCompat.ScrollAxis;
import android.view.MotionEvent;
import android.view.VelocityTracker;
import android.view.View;
import android.view.ViewConfiguration;
public interface NestedScrollingParent {
boolean onStartNestedScroll(@NonNull View child, @NonNull View target, @ScrollAxis int axes);
void onNestedScrollAccepted(@NonNull View child, @NonNull View target, @ScrollAxis int axes);
void onStopNestedScroll(@NonNull View target);
void onNestedScroll(@NonNull View target, int dxConsumed, int dyConsumed,int dxUnconsumed, int dyUnconsumed);
void onNestedPreScroll(@NonNull View target, int dx, int dy, @NonNull int[] consumed);
boolean onNestedFling(@NonNull View target, float velocityX, float velocityY, boolean consumed);
boolean onNestedPreFling(@NonNull View target, float velocityX, float velocityY);
@ScrollAxis
int getNestedScrollAxes();
}
复制代码
复杂版
package android.support.v4.view;
import android.support.annotation.NonNull;
import android.support.v4.view.ViewCompat.ScrollAxis;
import android.view.MotionEvent;
import android.view.VelocityTracker;
import android.view.View;
import android.view.ViewConfiguration;
public interface NestedScrollingParent {
//对启动nestable滚动操作的后代视图做出反应,如果合适的话,声明嵌套滚动操作。
此方法将被调用以响应调用startNestedScroll(view, int)的后代视图。视图层次结构中的每个父元素都有机会通过返回true来响应并声明嵌套的滚动操作。
ViewParent实现可能会重写此方法,以指示视图何时愿意支持即将开始的嵌套滚动操作。如果返回true,这个ViewParent将在滚动操作进行期间成为目标视图的嵌套滚动父视图。当嵌套滚动完成时,这个ViewParent将接收到对onStopNestedScroll(View)的调用。
boolean onStartNestedScroll(@NonNull View child, @NonNull View target, @ScrollAxis int axes);
//响应嵌套滚动操作的成功声明。
这个方法将在onStartNestedScroll返回true后调用。它为视图及其超类提供了为嵌套滚动执行初始配置的机会。如果存在超类,该方法的实现应该总是调用其超类的实现。
void onNestedScrollAccepted(@NonNull View child, @NonNull View target, @ScrollAxis int axes);
//响应嵌套的滚动操作结束。
执行嵌套滚动操作后的清理。当嵌套滚动停止时将调用此方法,例如当嵌套触摸滚动以ACTION_UP或ACTION_CANCEL事件结束时。如果存在超类,该方法的实现应该总是调用其超类的实现。
void onStopNestedScroll(@NonNull View target);
//对正在进行的嵌套滚动条作出反应。
当ViewParent的当前嵌套滚动子视图分派嵌套滚动事件时,将调用此方法。要接收对该方法的调用,ViewParent之前必须为调用onStartNestedScroll(View, View, int)返回true。
滚动距离的已使用部分和未使用部分都报告给ViewParent。例如,实现可以选择使用使用的部分来匹配或跟踪多个子元素的滚动位置。未使用的部分可用于允许连续拖动多个滚动或可拖动元素,例如在垂直抽屉内滚动列表,一旦到达内部滚动内容的边缘,抽屉就开始拖动列表。
void onNestedScroll(@NonNull View target, int dxConsumed, int dyConsumed,
int dxUnconsumed, int dyUnconsumed);
//在目标视图使用部分滚动之前,对正在进行的嵌套滚动进行响应。
在使用嵌套滚动时,父视图可能希望在嵌套滚动子视图之前使用滚动。其中一个例子是一个包含可滚动列表的抽屉。用户希望能够在列表本身开始滚动之前将列表完全滚动到视图中。
当嵌套滚动子调用dispatchNestedPreScroll(int, int, int[], int[])时,调用onNestedPreScroll。实现应该报告由dx、dy报告的滚动块的任何像素在使用的数组中是如何使用的。索引0对应dx,索引1对应dy,这个参数永远不会为空。消耗的[0]和消耗的[1]的初始值总是0。
void onNestedPreScroll(@NonNull View target, int dx, int dy, @NonNull int[] consumed);
//请求从嵌套的卷轴中弹出。
这个方法表示一个嵌套的滚动子节点已经检测到合适的触发条件。一般来说,这意味着触控滚动结束时,滚动方向的速度达到或超过可滚动轴上的最小抛速。
如果嵌套的滚动子视图通常会引发弹出,但它位于其自身内容的边缘,则可以使用此方法将引发的弹出委托给嵌套的滚动父视图。父母可以随意消费或观察孩子的放纵行为。
boolean onNestedFling(@NonNull View target, float velocityX, float velocityY, boolean consumed);
//在目标视图使用它之前对嵌套抛投做出反应。
这个方法表明嵌套的滚动子节点已经检测到沿每个轴的给定速度。一般来说,这意味着触控滚动结束时,滚动方向的速度达到或超过可滚动轴上的最小抛速。
如果嵌套的滚动父控件将运动作为预滚动的一部分使用,那么它也可以使用预动来完成相同的运动。通过从该方法返回true,父元素指示子元素也不应该抛出自己的内部内容。
boolean onNestedPreFling(@NonNull View target, float velocityX, float velocityY);
//返回这个NestedScrollingParent的嵌套滚动的当前轴。
返回SCROLL_AXIS_NONE以外内容的NestedScrollingParent目前充当层次结构中一个或多个后代视图的嵌套滚动父视图。
@ScrollAxis
int getNestedScrollAxes();
}
复制代码
自定义一个滚动组件所需要涉及到的知识
- 事件分发拦截
- 滚动知识
- 嵌套滚动相关