前言

本章主要讲解 NestedScrollView 嵌套滑动机制,我们在 如何应对Android面试官->嵌套滚动原理大揭秘,实战京东首页二级联动 中有简单介绍 NestedScrollView,本章我们重点解读下
嵌套滚动机制
我们先来回顾下事件分发机制(事件分发冲突与解决方案大揭秘)
- 事件的分发是从 Activity -> ViewGroup -> View
- 事件的消费是从 View -> ViewGroup -> Activity
- 事件的序列是从 Down -> Move -> Up/Cancel
前面的章节并没有提及 getScrollY() 指的是哪块区域,我们画两张图看下,白色区域表示屏幕,红色区域表示可滑动的 View:

向上滑动时候,getScrollY() 就是负值,根据 Android 坐标系的下正上负

那么向下滑动时候,getScrollY() 就是正值;
并且这个 getScrollY() 的结果是累加值;
前面讲解的时候,我们都是直接使用的 NestedScrollView,今天我们来手写一下的核心实现,嵌套滑动我们前面也说到了需要父 View 和子 View 配合使用才行,而我们的 NestedScrollView 实现了 NestedScrollingParent3 也实现了 NestedScrollingChild3,我们这里始终将 NestedScrollView 当做父容器,核心实现也只实现其作为父容器的部分,感兴趣的可以自行实现其作为子容器的逻辑部分,所以我们只需要实现 NestedScrollingParent 接口即可;
public class NestedScrollingParentLayout extends LinearLayout implements NestedScrollingParent {
public NestedScrollingParentLayout(Context context) {
super(context);
}
public NestedScrollingParentLayout(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
}
public NestedScrollingParentLayout(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
setOrientation(VERTICAL);
}
@Override
public void onNestedScroll(@NonNull View target, int dxConsumed, int dyConsumed, int dxUnconsumed, int dyUnconsumed, @NonNull int[] consumed) {
}
/**
* 当NestedScrollingChild调用方法startNestedScroll()时,会调用该方法。主要就是通过返
* 回值告诉系统是否需要对后续的滚动进行处理
* child:该ViewParent的包含 NestedScrollingChild 的直接子 View,如果只有一层嵌套,和
* target是同一个View
* target:本次嵌套滚动的NestedScrollingChild
* nestedScrollAxes:滚动方向
* @return
* true:表示我需要进行处理,后续的滚动会触发相应的回到
* false: 我不需要处理,后面也就不会进行相应的回调了
*/
// child 和 target 的区别,如果是嵌套两层如:Parent包含一个LinearLayout,LinearLayout里
// 面才是 NestedScrollingChild 类型的View。这个时候,
// child 指向 LinearLayout,target 指向 NestedScrollingChild;如果 Parent 直接就包含了
// NestedScrollingChild,
// 这个时候 target 和 child 都指向 NestedScrollingChild
@Override
public boolean onStartNestedScroll(@NonNull View child, @NonNull View target, int axes) {
return false;
}
/**
* 如果onStartNestedScroll()方法返回的是true的话,那么紧接着就会调用该方法.它是让嵌套滚
* 动在开始滚动之前,
* 让布局容器(viewGroup)或者它的父类执行一些配置的初始化的
*/
@Override
public void onNestedScrollAccepted(@NonNull View child, @NonNull View target, int axes, int type) {
}
/**
* 停止滚动了,当子view调用stopNestedScroll()时会调用该方法
*/
@Override
public void onStopNestedScroll(@NonNull View target) {
}
/**
* 当子view调用dispatchNestedScroll()方法时,会调用该方法。也就是开始分发处理嵌套滑动了
* dxConsumed:已经被target消费掉的水平方向的滑动距离
* dyConsumed:已经被target消费掉的垂直方向的滑动距离
* dxUnconsumed:未被tagert消费掉的水平方向的滑动距离
* dyUnconsumed:未被tagert消费掉的垂直方向的滑动距离
*/
@Override
public void onNestedScroll(@NonNull View target, int dxConsumed, int dyConsumed, int dxUnconsumed, int dyUnconsumed) {
}
/**
* 当子view调用dispatchNestedPreScroll()方法是,会调用该方法。也就是在
* NestedScrollingChild在处理滑动之前,
* 会先将机
Android NestedScrollView嵌套滑动机制解析

本文重点讲解 Android 中 NestedScrollView 的嵌套滑动机制。回顾了事件分发机制,介绍嵌套滑动的四个阶段,包括初始、预滚动、滚动和结束阶段。还给出了核心实现,包括布局和事件处理,最后提到简历可写相关技能,预告下一站讲解协调者布局的 behavior。
最低0.47元/天 解锁文章
8603

被折叠的 条评论
为什么被折叠?



