用途
本技能面向使用 Jetpack Compose 开发 Android 界面的开发者,专门解决垂直滑动过渡动画的一个隐蔽陷阱:slideInVertically() 与 slideOutVertically() 在不传入 offset lambda 时,默认从元素自身高度的一半开始(-it/2),而不是从完全离屏的位置开始。这会让元素在第一帧就已经走完一半行程,视觉上像是“跳”了一下,前半段动画缺失。
主要能力
- 指出默认值问题:通过反编译动画库产物(
javap查看EnterExitTransitionKt)确认默认偏移是-it / 2,进入和退出两个方向都如此。 - 给出正确写法:提供
BarEnter/BarExit示例,用{ -it }让元素从完整高度外滑入,并配合fadeIn使用。 - 揭示方向陷阱:默认值已带负号,所以传
{ it }会反转方向——原本从上方进入变成从下方进入,属于意外改变设计。 - 说明布局行为差异:滑动是平移,元素在整个动画期间占据最终槽位,不会引起周围元素重排;而
AnimatedVisibility的默认 enter 是淡入加尺寸展开(expandIn),会触发重排。用fadeIn() + slideInVertically()会替换掉展开动画。 - 时长比例建议:淡入时长应短于滑动时长(示例 180ms 对 260ms,约三分之二),避免元素停下后还在变透明、看起来“安定两次”;退出应快于进入(示例 140/200 对 180/260),因为离开不应占用用户注意力。
- 共享常量化:建议把这对过渡定义为共享文件中的顶层
val,避免每个屏幕各自内联、逐渐漂移,也便于用 grep 检查一致性。 - 审计方法:提供 grep 命令分别统计三种写法(无参调用、带括号传参、尾随 lambda 无括号),并给出了解总数与 import 数的对照方法,提醒两种模式审计会漏掉第三种写法。
- 验证步骤:手动录屏逐帧检查第一可见帧是否完全在槽位外,并观察透明度是否在停止移动前已不透明。
使用方式
在代码中将滑动过渡显式传入 { -it }(从顶部下降)或 { it }(从底部上升),按需决定方向;将进入/退出过渡对抽取为共享常量;用提供的 grep 命令在代码库中搜索裸调用并按需修正;可选用 javap 命令确认库的默认实现。
适用场景
适用于任何使用 Compose AnimatedVisibility 或过渡 API 实现垂直滑入/滑出动画的界面,尤其是多人协作、多个屏幕复用同一控件动画的项目。裸调用不会报错,linter 也不会发现,因此需要主动审计。
限制
技能仅涉及 Compose 垂直滑动过渡的默认偏移与时长比例,不涉及水平滑动或其他动画类型;示例中的具体毫秒数和比例是建议起点而非强制规范;未提及对性能、无障碍或其他平台的影响。