Android嵌套滑动框架的一点理解

329 阅读3分钟

嵌套滑动框架的接口有两套

NestedScrollingChild

NestedScrollingParent

NestedScrollingChild2

NestedScrollingParent2

理解一、

android 从5.0开始提供了嵌套滑动框架

Support和androidx里面又提供了一套兼容框架

这两个是要搭配起来用

打个比方

你用support或者androidx里面的view(比如recycleView)那就要使用support或者androidx里面提供的嵌套滑动接口

如果用的是android框架自带的view,那就要使用android框架里面的嵌套滑动接口,否则实测会有冲突

如果你用support或者androidx,那就要使用NestedScrollingChild2和NestedScrollingParent2,因为这两个处理了一些bug,据说是与fling相关

理解二、

无论是NestedScrollingChild和NestedScrollingParent还是NestedScrollingChild2和NestedScrollingParent2,他本身提供的就是一套接口,基于接口的分发逻辑是写在helper里面的

理解三、

一般来讲,滚动组件都是父控件,滚动的处理逻辑一般基于事件拦截和事件回溯,也就是说父滚动控件优先拦截触摸事件,一但拦截成功用于滚动消耗,就不会再将触摸时间给子view

及时拦截不成功,当子view无法消耗触摸事件时,触摸时间也会回溯到父滚动容器进行滚动消耗

因此在这个实现原理下,我们很难通过对触摸事件的控制来完成父子连贯的嵌套滚动处理

理解四、

这套滚动嵌套框架的实现原理同样是基于事件分发原则,不过这里的事件不是触摸事件,而是指滚动事件

要实现嵌套滚动,整个过程为如下几个步骤

1、父控件不拦截触摸事件用于滚动

2、触摸事件到达子View,子View判断父view是否需要滚动,如果需要滚动就把滚动的事件交给父view

3、父view滚动完成后会告诉子view自己滚动了多少,如果已经滚到不能再滚了,就把未消耗的滚动距离告诉子view,子view再消耗剩下的滚动距离

4、如果最后子view还是没消耗完,就再重新发给父view消耗

理解五、

一般来讲,android5.0以后的一些滚动组件和androidx包里面的滚动组件都已经实现了嵌套滚动特性,如果要自己同时实现child和parent实现嵌套还是比较复杂的
从目前的情况下 想继承一个已经写好的滑动容器的基础上,然后实现嵌套滑动,可能性不太大,这一点从Google官方提供的NestedScrollView来看也是用一个FrameLayout
写出来的,不是继承自ScrollView

如果要实现一个自己的NestedScrollingChild2,那么你就要完全控制滚动容器的touch事件和滚动事件,通过调用NestedScrollingChild2提供的几个方法实现滚动事件的分发,很复杂

所以一搬在使用的时候 NestedScrollingChild都是别人写好的,比如框架提供的NestedScrollView,RecycleView等,然后自己实现一个Parent,比如可以继承自LinearLayout