如何在Jetpack Compose中实现布尔值变化时的抖动动画?
在Jetpack Compose中触发状态变化时实现抖动动画
你可以通过关键帧动画或手动控制动画序列实现需求——不需要改变最终状态,仅在布尔值触发时让元素完成一次抖动后回到原位。以下是两种可行方案:
方案一:使用animateFloatAsState配合关键帧
利用keyframes动画规范,让动画的起始和结束值均为0,但在中间时间点设置偏移量,从而产生抖动效果。
@Composable fun ShakeAnimationDemo() { var text by remember { mutableStateOf("") } var isError by remember { mutableStateOf(false) } // 抖动偏移量:起始和结束都是0,中间通过关键帧实现左右晃动 val shakeOffset by animateFloatAsState( targetValue = 0f, // 始终以0为目标值 animationSpec = keyframes { durationMillis = 500 // 抖动总时长 10f at 100ms // 100ms时向右偏移10dp -10f at 200ms // 200ms时向左偏移10dp 8f at 300ms // 300ms时向右偏移8dp -5f at 400ms // 400ms时向左偏移5dp 0f at 500ms // 500ms时回到原位 }, // 动画结束后重置状态,确保下次触发有效 finishedListener = { isError = false } ) Column(modifier = Modifier.padding(16.dp)) { TextField( value = text, onValueChange = { text = it }, label = { Text("输入内容") }, modifier = Modifier .offset(x = shakeOffset.dp) // 将偏移量转为dp单位 .fillMaxWidth() ) Button( onClick = { isError = true }, // 触发抖动 modifier = Modifier.padding(top = 16.dp) ) { Text("触发抖动") } } }
方案二:使用Animatable手动控制动画序列
通过Animatable连续执行多个小动画,手动控制每一次的偏移和时长,灵活性更高。
@Composable fun ManualShakeDemo() { var text by remember { mutableStateOf("") } var isError by remember { mutableStateOf(false) } val shakeAnimatable = remember { Animatable(0f) } // 当isError状态变化时启动动画序列 LaunchedEffect(isError) { if (isError) { // 依次执行偏移动画,模拟抖动 shakeAnimatable.animateTo(10f, animationSpec = tween(100)) shakeAnimatable.animateTo(-10f, animationSpec = tween(100)) shakeAnimatable.animateTo(8f, animationSpec = tween(100)) shakeAnimatable.animateTo(-5f, animationSpec = tween(100)) shakeAnimatable.animateTo(0f, animationSpec = tween(100)) // 动画结束后重置状态 isError = false } } Column(modifier = Modifier.padding(16.dp)) { TextField( value = text, onValueChange = { text = it }, label = { Text("输入内容") }, modifier = Modifier .offset(x = shakeAnimatable.value.dp) .fillMaxWidth() ) Button( onClick = { isError = true }, modifier = Modifier.padding(top = 16.dp) ) { Text("触发抖动") } } }
注意事项
- 两种方案都需要在动画结束后重置
isError状态,否则再次触发时因为状态未变化,动画不会重新执行。 - 可以调整关键帧的
durationMillis、偏移量数值或tween的时长,来控制抖动的幅度、频率和整体节奏。 - 偏移量使用
dp单位是为了适配不同屏幕,避免在高分辨率设备上抖动效果不明显。
内容的提问来源于stack exchange,提问作者pafi
相关产品推荐
相关产品推荐

