嵌套滑动造成的滑动冲突原理分析
场景复现:
CoordinatorLayout + AppBarLayout + Vertical RecyclerView + Horizontal RecycleView
Horizontal RecycleView 是Vertical RecyclerView的一个子view, CoordinatorLayout 实现了AppBarLayout 和 RecyclerView的协调联动,在向上滑动RecyclerView的时候,会先滑动AppBarLayout,再滑动RecyclerView,问题场景是在点击Horizontal RecycleView,然后向上滑动时,造成了Vertical RecyclerView 滑动,而AppBarLayout 没有滑动。
原理解析:
Behavior的概念
Behavior用于为特定的子 View 定义自定义的交互行为,它通常与 CoordinatorLayout 一起使用,允许开发者在 View 之间创建复杂的滚动、滑动、拖拽等行为。
Behavior 提供了一些关键的回调方法,用于处理事件:
| 方法 | 描述 |
|---|---|
onInterceptTouchEvent |
是否拦截触摸事件。 |
onTouchEvent |
处理触摸事件。 |
onStartNestedScroll |
是否开始处理嵌套滑动事件。 |
onNestedScrollAccepted |
当嵌套滑动被接受时调用。 |
onNestedPreScroll |
嵌套滑动事件之前调用,用于消费部分或全部滑动。 |
onNestedScroll |
在嵌套滑动期间调用,用于处理滑动的剩余部分。 |
onStopNestedScroll |
嵌套滑动结束时调用。 |
layoutDependsOn |
定义该 Behavior 是否依赖另一个 View。 |
onDependentViewChanged |
当依赖的 View 发生变化时调用(如位置或大小变化)。 |
CoordinationLayout + AppBarLayout + Vertical RecycleView是如何实现联动的呢?
1.点击AppBarLayout 位置时
AppBarLayout 不会消费事件,会将事件传递给CoordinationLayout#onTouchEvent()
if (mBehaviorTouchView != null || (cancelSuper = performIntercept(ev, TYPE_ON_TOUCH))) {
// Safe since performIntercept guarantees that
// mBehaviorTouchView != null if it returns true
//mBehaviorTouchView 就是AppBarLayout
final LayoutParams lp = (LayoutParams) mBehaviorTouchView.getLayoutParams();
final Behavior b = lp.getBehavior();
if (b != null) {
handled = b.onTouchEvent(this, mBehaviorTouchView,

最低0.47元/天 解锁文章
1万+

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



