安卓的嵌套滚动一

·  阅读 71

嵌套滚动实现接口

  1. 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);
}

复制代码
  1. 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();
}

复制代码

自定义一个滚动组件所需要涉及到的知识

  1. 事件分发拦截
  2. 滚动知识
  3. 嵌套滚动相关
收藏成功!
已添加到「」, 点击更改