android嵌套滚动入门实践

嵌套滚动是 Android OS 5.0之后,google 为我们提供的新特性。这种机制打破了我们对之前 Android 传统的事件处理的认知。从一定意义上可以理解为嵌套滚动是逆向的事件传递机制。

如上图所示,其原理就是这样。那么下边我们从代码的层面看一下实现。

代码中主要涉及到了四个类:

NestedScrollingChild、NestedScrollingChildHelper、NestedScrollingParent、NestedScrollingParentHelper

先看NestedScrollingChild 接口中定义的方法:

public interface NestedScrollingChild {
  /**
   * 设置是否启用嵌套滚动
   */
  public void setNestedScrollingEnabled(boolean enabled);

  /**
   * 判断是否启用嵌套滚动
   */
  public boolean isNestedScrollingEnabled();

  /**
   * 开始嵌套滚动
   * @param axes 标识方向,有 x, y 方形和默认值0
   */
  public boolean startNestedScroll(int axes);

  /**
   * 嵌套滚动结束
   */
  public void stopNestedScroll();

  /**
   * 判断父 view 是否支持嵌套滚动
   */
  public boolean hasNestedScrollingParent();

  /**
   * 分发嵌套滚动,一般再 onTouch/onInterceptTouchEvent/dispatchTouchEvent 中调用
   * @param dxConsumed x轴滚动的距离
   * @param dyConsumed y 轴滚动的距离
   * @param dxUnconsumed x 轴上未消费的距离
   * @param dyUnconsumed y 轴上未消费的距离
   * @param offsetInWindow 子 View 的窗体偏移
   */
  public boolean dispatchNestedScroll(int dxConsumed, int dyConsumed,
      int dxUnconsumed, int dyUnconsumed, int[] offsetInWindow);

  /**
   * 滚动之前调用,进行分发预滚动事件
   */
  public boolean dispatchNestedPreScroll(int dx, int dy, int[] consumed, int[] offsetInWindow);

  /**
   * 滑动时调用 ,分发滑动事件
   */
  public boolean dispatchNestedFling(float velocityX, float velocityY, boolean consumed);

  /**
  * 滚动之前调用,分发预滚动事件
   */
  public boolean dispatchNestedPreFling(float velocityX, float velocityY);
}
NestedScrollingParent 接口中的方法均是与NestedScrollingChild 中的方法一一对应的:

public interface NestedScrollingParent {

  public boolean onStartNestedScroll(View child, View target, int nestedScrollAxes);

  public void onNestedScrollAccepted(View child, View target, int nestedScrollAxes);

  public void onStopNestedScroll(View target);

  public void onNestedScroll(View target, int dxConsumed, int dyConsumed,
      int dxUnconsumed, int dyUnconsumed);

  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();
}

以上两个类仅仅是定义了功能接口,真正的实现的代码都包含在了NestedScrollingChildHelper和NestedScrollingParentHelper中。

处理流程:

1、当 NestedScrollingChild(下文用Child代替) 要开始滑动的时候会调用 onStartNestedScroll ,然后交给代理类NestedScrollingChildHelper(下文ChildHelper代替)的onStartNestedScroll请求给最近的NestedScrollingParent(下文Parent代替).

2、当ChildHelper的onStartNestedScroll方法 返回 true 表示同意一起处理 Scroll 事件的时候时候,ChildHelper会通知Parent回调onNestedScrollAccepted 做一些准备动作

3、当Child 要开始滑动的时候,会先发送onNestedPreScroll,交给ChildHelper的onNestedPreScroll 请求给Parent ,告诉它我现在要滑动多少距离,你觉得行不行,这时候Parent 根据实际情况告诉Child 现在只允许你滑动多少距离.然后 ChildHelper根据 onNestedPreScroll 中回调回来的信息对滑动距离做相对应的调整.

4、在滑动的过程中 Child 会发送onNestedScroll通知ChildeHelpaer的onNestedScroll告知Parent 当前 Child 的滑动情况.

5、当要进行滑行的时候,会先发送onNestedFling 请求给Parent,告诉它 我现在要滑行了,你说行不行, 这时候Parent会根据情况告诉 Child 你是否可以滑行.

6、Child 通过onNestedFling 返回的 Boolean 值来觉得是否进行滑行.如果要滑行的话,会在滑行的时候发送onNestedFling 通知告知 Parent 滑行情况.

7、当滑动事件结束就会child发送onStopNestedScroll通知 Parent 去做相关操作.

废话不多说了,看代码和 demo 才是正事儿。https://github.com/JeffWangGithub/StickLayout

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • Android NestedScrolling嵌套滚动的示例代码

    一.什么是NestedScrolling? Android在Lollipop版本中引入了NestedScrolling--嵌套滚动机制.在Android的事件处理机制中,事件序列只能由父View和子View中的一个处理.在嵌套滚动机制中,子View处理事件前会将事件传给父View处理,两者协作配合处理事件. 在嵌套滚动机制中,父View需实现NestedScrollingParent接口,子View需要实现NestedScrollingChild接口.从Lollipop起View都已经实现了Ne

  • android嵌套滚动入门实践

    嵌套滚动是 Android OS 5.0之后,google 为我们提供的新特性.这种机制打破了我们对之前 Android 传统的事件处理的认知.从一定意义上可以理解为嵌套滚动是逆向的事件传递机制. 如上图所示,其原理就是这样.那么下边我们从代码的层面看一下实现. 代码中主要涉及到了四个类: NestedScrollingChild.NestedScrollingChildHelper.NestedScrollingParent.NestedScrollingParentHelper 先看Nest

  • Android嵌套滚动与协调滚动的实现方式汇总

    目录 Android的协调滚动的几种实现方式 一.CoordinatorLayout + Behavior 二.CoordinatorLayout + AppBarLayout 三.MotionLayout 总结 Android的协调滚动的几种实现方式 上一期,我们讲了嵌套滚动的实现方式,为什么有了嵌套滚动还需要协调滚动这种方式呢?(不细讲原理,本文只探讨实现的方式与步骤!) 那在一些细度化的操作中,如我们需要一些控件随着滚动布局做一些粒度比较小的动画.移动等操作,那么我们就需要监听滚动,然后改

  • Android嵌套滚动的传统方法与思路

    前言 Android 的嵌套滚动,实现比较方便 横着滚动,ViewPager2 竖着滚动,NestedScrollingParent 顶上,有一个头部视图 header, 中间,有一个菜单视图 menu, 下面的是,内容视图, 一个 ViewPager2,包含几个 Tab, Tab 里面是列表 RecyclerView 本文,主要参考  hongyangAndroid/Android-StickyNavLayout Java 实现 基于 LinearLayout ,添加 NestedScroll

  • Android嵌套滚动和协调滚动的多种实现方法

    目录 Android的嵌套滚动的几种实现方式 一.嵌套滚动 NestedScrollingParent/Child 二.嵌套滚动 NestedScrollView 三.嵌套滚动-自定义布局 总结 Android的嵌套滚动的几种实现方式 很多 Android 开发者虽然做了几年的开发,但是可能还是对滚动的几种方式不是很了解,本系列也不会涉及到底层滚动原理,只是探讨一下 Android 布局滚动的几种方式. 什么叫嵌套滚动?什么叫协调滚动? 只要是涉及到滚动那必然父容器和子容器,按照原理来说子容器先

  • Android嵌套滚动NestedScroll的实现了解一下

    其实嵌套滚动已经算一个比较常见的特效了,下面这个动图就是嵌套滚动的一个例子: 看到这个动效,大家可能都知道可以用CoordinatorLayout去实现.其实CoordinatorLayout是基于NestedScroll机制去实现的,而我们直接通过NestedScroll机制也能很方便的实现这个动效. 原理 NestedScroll的其实很简单. 一般的触摸消息的分发都是从外向内的,由外层的ViewGroup的dispatchTouchEvent方法调用到内层的View的dispatchTou

  • Android 三级NestedScroll嵌套滚动实践

    嵌套滚动介绍 我们知道 NestedScrolling(Parent/Child) 这对接口是用来实现嵌套滚动的,一般实现这对接口的 Parent 和 Child 没有直接嵌套,否则直接用 onInterceptTouchEvent() 和 onTouchEvent() 这对方法实现就可以了.能够越级嵌套滚动正是它的厉害之处. 嵌套滚动的接口有两对:NestedScrolling(Parent/Child) 和 NestedScrolling(Parent2/Child2) 后者相比前者对 fl

  • 函数式编程入门实践(一)

    在文章之前,先和大家讲一下对于函数式编程(Functional Programming, aka. FP)的理解(下文我会用FP指代函数式编程): FP需要保证函数都是纯净的,既不依赖外部的状态变量,也不产生副作用.基于此前提下,那么纯函数的组合与调用,在时间顺序上就不会产生依赖,改变多个函数的调用顺序也不必担心产生问题,因此也会消灭许多潜在的bug. 函数必须有输入输出.如果一个函数缺乏输入或输出,那么它其实是一段处理程序procedure而已. 函数尽可能的保持功能的单一,如果一个函数做了多

  • android自定义滚动上下回弹scollView

    本文实例为大家分享了android自定义滚动上下回弹scollView的具体代码,供大家参考,具体内容如下 这是一个自定义view,在xml布局中用这个view嵌套要使之可以上下回弹的view 就能实现布局可以滚动上下回弹了,自定义view代码如下: package com.loopfire.meitaotao.view.scrollView;   import android.content.Context; import android.graphics.Rect; import andro

  • Android嵌套RecyclerView左右滑动替代自定义view

    以前的左右滑动效果采用自定义scrollview或者linearlayout来实现,recyclerview可以很好的做这个功能,一般的需求就是要么一个独立的左右滑动效果,要么在一个列表里的中间部分一个左右滑动效果 而列表里面也容易,只是需要解决一点小问题,个人认为值得一提的就是高度问题,一般的人采用固定死的高度,可是在列表里面展示和机型的不同,固定死的话很难保证美观,动态的高度才能解决问题的所在 首先在一个列表控件布局上添加一个recyclerview控件 <android.support.v

随机推荐