Jetpack Compose波浪文字动画:序列错乱问题求助
问题根源
你当前的动画错乱问题,核心在于tween的delayMillis仅在第一次动画周期启动时生效。当infiniteRepeatable进入反向或重复循环时,这个延迟不会再次触发,导致后续循环中字母的动画同步逻辑失效,不再保持依次缩放的顺序。
解决方案
以下两种方法均可解决该问题,推荐第二种,更易于调整整体动画节奏:
方法1:用keyframes嵌入循环内的延迟逻辑
将每个字母的延迟、缩放、反向逻辑全部写入关键帧,确保每次循环都严格遵循顺序:
@Composable fun AnimatedText(word: String) { val duration = 500L val delayPerItem = 100L val transition = rememberInfiniteTransition() Row(horizontalArrangement = Arrangement.spacedBy(4.dp)) { word.forEachIndexed { index, c -> val totalCycleDuration = duration * 2 // 正向放大+反向缩小的总时长 val initialDelay = delayPerItem * index val scale by transition.animateFloat( initialValue = 1f, targetValue = 1f, // 关键帧会覆盖最终值,此处填初始值即可 animationSpec = infiniteRepeatable( animation = keyframes { durationMillis = totalCycleDuration.toInt() // 正向阶段:先等待对应延迟,再放大到2f 1f at initialDelay.toInt() 2f at (initialDelay + duration).toInt() // 反向阶段:保持放大状态到周期中点,再缩小回1f 2f at (totalCycleDuration / 2 + initialDelay).toInt() 1f at (totalCycleDuration + initialDelay).toInt() }, repeatMode = RepeatMode.Restart ), label = "" ) Text(text = c.toString(), fontSize = (24 * scale).sp) } } }
方法2:基于全局进度控制单个字母动画
创建一个全局循环进度,每个字母根据自身索引计算偏移后的进度,再映射到缩放值,逻辑更统一可控:
@Composable fun AnimatedText(word: String) { val duration = 500L val delayPerItem = 100L val transition = rememberInfiniteTransition() // 总周期:覆盖所有字母完成一次放大+缩小的时长 val totalCycle = duration * 2 + delayPerItem * (word.length - 1) val progress by transition.animateFloat( initialValue = 0f, targetValue = 1f, animationSpec = infiniteRepeatable( animation = tween(totalCycle.toInt(), easing = LinearEasing), repeatMode = RepeatMode.Restart ), label = "" ) Row(horizontalArrangement = Arrangement.spacedBy(4.dp)) { word.forEachIndexed { index, c -> // 计算当前字母的进度(减去自身延迟偏移) val letterProgress = (progress * totalCycle - delayPerItem * index) .coerceAtLeast(0f) / (duration * 2) // 映射进度到缩放值:0→1f(放大),0.5→2f,1→1f(缩小) val scale = when { letterProgress <= 0.5f -> 1f + letterProgress * 2f else -> 2f - (letterProgress - 0.5f) * 2f }.coerceIn(1f, 2f) Text(text = c.toString(), fontSize = (24 * scale).sp) } } }
内容的提问来源于stack exchange,提问作者Oleksandr Myronchuk
相关产品推荐
相关产品推荐

