Jetpack Compose中如何为LazyRow各元素单独延迟矢量动画Drawable播放
Compose 启动页星星序列动画实现方案
实现效果参考:
现有代码核心问题
- 加载的
Animator实例未和AnimatedVectorDrawable绑定,设置的startDelay完全未生效 - 所有星星组件的动画启动逻辑无延迟控制,组件挂载后立刻触发动画,导致同时播放
- 在Lazy列表的items块中直接修改remember状态变量,重组时会重复累加延迟值,导致延迟逻辑混乱
第一步:改造星星子组件,增加启动延迟参数
修改StarNormalItem,接收启动延迟入参,在动画启动前先等待指定时长,同时补充循环播放逻辑匹配xml中动画的无限重复配置:
@OptIn(ExperimentalAnimationGraphicsApi::class) @Composable fun StarNormalItem( modifier: Modifier = Modifier, startDelay: Long = 0L ) { val star = animatedVectorResource(id = R.drawable.star_normal_animated) var atEnd by remember { mutableStateOf(false) } Image( painter = star.painterFor(atEnd = atEnd), contentDescription = "star", modifier = modifier ) LaunchedEffect(Unit) { // 等待指定延迟后再启动动画 delay(startDelay) // 循环切换状态匹配xml中无限重复的动画配置 while (true) { atEnd = !atEnd // 等待时长和xml中动画duration保持一致 delay(1500L) } } }
第二步:改造列表组件,按位置分配延迟时长
删除无用的Animator加载逻辑,直接用列表下标计算每个星星的启动延迟:
@OptIn(ExperimentalAnimationGraphicsApi::class) @Composable fun StarNormalList(modifier: Modifier = Modifier) { var starPosition by remember { mutableStateOf(false) } LazyRow(modifier = modifier) { items(20) { index -> StarNormalItem( Modifier .padding(10.dp) .offset(0.dp, if (starPosition) 10.dp else (-10).dp) .mediaQuery( Dimensions.Width greaterThan 400.dp, modifier = Modifier.size(40.dp, 40.dp) ), // 每个星星依次叠加100ms启动延迟 startDelay = index * 100L ) starPosition = !starPosition } } }
补充注意事项
确认star_normal_animated.xml中target的动画资源指向正确,如果你使用的是贴出的rotation_and_morph动画文件,需要修改配置:
<animated-vector xmlns:android="http://schemas.android.com/apk/res/android" android:drawable="@drawable/star_normal"> <target android:animation="@animator/rotation_and_morph" android:name="star_normal_group" /> </animated-vector>
内容的提问来源于stack exchange,提问作者Loïc Jackotin
相关产品推荐
相关产品推荐

