Skip to content

android-nested-scroll-coordination-demo ​

1. 实验目标 ​

围绕“折叠头部 + 列表继续滚”这条主线,同时验证 Android 的两套完整实现:

  • Compose:Modifier.nestedScroll() + NestedScrollConnection
  • Android View:CoordinatorLayout + AppBarLayout + RecyclerView

核心不是比较谁代码短,而是看清:

  • Compose 侧是显式位移消费链
  • View 侧是容器 behavior 编排
  • 两者都在解决“共享滚动位移”的同一类问题

2. 原理与思路 ​

2.1 Compose 为什么像“位移分账” ​

Compose 会在滚动前后把可用位移、已消费位移、剩余位移显式交给 NestedScrollConnection。你要自己决定:

  • 头部先吃多少
  • 列表再吃多少
  • 边界时父级要不要补消费

2.2 Android View 为什么像“容器行为编排” ​

传统 View 体系把 nested scrolling parent/child 协议藏在容器与 behavior 里:

  • AppBarLayout 知道自己能折叠
  • RecyclerView 把滚动继续交给 AppBarLayout 或自己消费
  • CoordinatorLayout 负责把行为连接起来

开发时经常会觉得“没写多少逻辑就能跑”,但问题是调试时很难看到每一段位移到底被谁吃掉了。

2.3 方案对比矩阵 ​

方案通俗比喻底层原理保证特性吞吐性能运行开销适用场景
Compose NestedScroll自己拿着账本给每一方分位移pre/post scroll + fling 回调位移消费顺序显式可控高中Compose 页面、复杂局部联动
View CoordinatorLayout让调度员按既定规则分派滚动nested scrolling parent/child + behavior经典折叠头、吸顶联动稳定高低到中旧页面、XML 体系、迁移阶段
Flutter NestedScrollView让 Sliver 结构统一协调 outer/inner scrollouter/inner ScrollPosition + Sliver 协同头部折叠 + 内部列表稳定高中Flutter 页面主方案

3. Android / 移动端实战场景与误配事故 ​

3.1 实战场景 ​

  • 个人主页折叠头图
  • 搜索页吸顶过滤栏
  • 商品详情头图折叠 + 详情列表
  • BottomSheet 内部长列表

3.2 常见误配与事故注意事项 ​

  • 直接给外层套 ScrollView 再把 RecyclerView 塞进去
  • Compose 顶层反复读取 offset,滚一下整页重组
  • Flutter 用 ScrollController 强行监听,却没把需求落回 Sliver 结构

3.3 排障思路 ​

  1. 先问是不是“共享位移”问题,而不是普通列表题
  2. 再确认滚动主语是谁:头部、列表、sheet 还是外层容器
  3. 再看边界:谁先吃,谁后吃,滚不动后谁接手
  4. 最后才看 API 选型

4. 实验源码与运行验证 ​

关键源码 ​

关键参数 / 开关 ​

  • maxHeaderOffsetPx:Compose 头部最多折叠多少像素
  • Compose / View Tab:切换两种实现,便于对照折叠行为
  • manual offset label:观察头部当前折叠量与列表首项位置

运行方式 ​

bash
cd labs/android/host
./gradlew assembleDebug

安装后打开 Android Host → 打开 Android 嵌套滚动协同实验室。

预期现象 ​

  • Compose Tab:先折叠头部,再滚列表
  • View Tab:AppBarLayout 先收起,再由 RecyclerView 继续滚
  • 两边都能观察到“头部先吃,列表后吃”的一致结果

5. 对应知识库文档 ​

站点构建时间:2026/8/24 23:43:17