记录一个AppBarLayout的bugfix修复

问题现象: CoordinatorLayout嵌套 上半部分AppBarLayout+下半部分RecyclerView, 对下半部分RecyclerView的显示隐藏做操作(如吟唱recyclerView展示一个ErrorLayout or EmptyLayout, 会导致AppBarLayout区域不再响应滑动, 这个bug较容易忽略, 因为滑动界面上的下半部分立即可以恢复滑动使现象消失.

这个问题是由系统源码导致, 里记录一下原因分析:

从CoordinatorLayout看起:

HeaderBehavior:

AppBarlayout:

lastNestedScrollingChildRef的赋值只有两处,

less 复制代码
@Override
public boolean onStartNestedScroll(
    @NonNull CoordinatorLayout parent,
    @NonNull T child,
    @NonNull View directTargetChild,
    View target,
    int nestedScrollAxes,
    int type) {
  //省略...
  // A new nested scroll has started so clear out the previous ref
  lastNestedScrollingChildRef = null;
  //省略...
  return started;
}

@Override
public void onStopNestedScroll(
    CoordinatorLayout coordinatorLayout, @NonNull T abl, View target, int type) {

  //省略... 
  // Keep a reference to the previous nested scrolling child
  lastNestedScrollingChildRef = new WeakReference<>(target);
}

所以lastNestedScrollingChildRef得含义和名字一样, 是上一次的嵌套滚动view, 如果我们滑动了RecyclerView, 那么这个值就是RecyclerView, 如果此时把RecyclerView隐藏, 再滑动AppBarLayout区域, 就会滑不动了, 因为AppBarLayout中CanDragView中判断RecyclerView isShown()为false.

为什么滑动一下AppBarLayout下面的错误界面或空界面区域就会恢复呢? 因为在View中有如下一段代码:

scss 复制代码
public boolean dispatchTouchEvent(MotionEvent event) {
    //...
    final int actionMasked = event.getActionMasked();
    if (actionMasked == MotionEvent.ACTION_DOWN) {
        // Defensive cleanup for new gesture
        stopNestedScroll();
    }
    //...

由前面源码得知, stopNestedScroll();中会对lastNestedScrollingChildRef重新赋值. 这也是为什么是在 lastNestedScrollingChildRef是在stopNestedScroll();中赋值, 而每次开始滑动是lastNestedScrollingChildRef总是不为空.

至此, AppBarLayout偶现滑不动的原因就清楚了.

相关推荐
海水冷却8 小时前
Android 群组聊天怎么实现:基于 ZIM 的完整落地指南(附可运行 Demo)
android
三少爷的鞋11 小时前
现代 Android 架构指南:不要再主动设计 Callback 接口
android
TimeFine17 小时前
AI 编码工作流的设计
android·ai编程
骑着蜗牛撵大象32717 小时前
C++20 协程 × 屏障:手写一个 co_await 版 Barrier,让等待不再钉死线程
android·c++20·协程·并发编程·co_await·屏障同步
山东孙燕姿19 小时前
设备台账重构:从一张表到三层模型
android·java·网络·低代码·重构·rxjava
蒸鱼Yuzheng20 小时前
移动端 CPU 调度分析:线程亲和性、大小核迁移与卡顿
android·perfetto·性能分析·线程优化·cpu调度
booboosui20 小时前
安卓唤醒词:12 维 MFCC 加 DTW,阈值 1.8
android
传奇开心果20 小时前
Compose Multiplatform 共享边界实战:架构契约、互操作同步与可回退设计
android·kotlin
事圆则缓21 小时前
从开机到首帧:Android 系统与应用启动流程源码分析
android
AI吃大瓜21 小时前
指针压力表读数4:Android实现指针压力表读数(可实时检测)
android·指针读数·指针压力表·压力表·压力表读数