Jetpack Compose:如何让AnimatedVisibility动画不超出父布局边界?
解决Compose AnimatedVisibility横向动画超出父布局边界的问题
不需要使用底层动画API,有两种简单的解决方案:
方案一:给父容器添加裁剪修饰符
直接给外层Box添加clipToBounds(true),动画过程中超出父布局的部分会被自动裁剪,这是最快捷的处理方式:
var isVisible by remember { mutableStateOf(true) } Button(onClick = { isVisible = !isVisible }) { Text("Click") } Box( modifier = Modifier .width(300.dp) .height(16.dp) .background(Color.Blue.copy(alpha = 0.5F)) .clipToBounds(true) // 添加裁剪修饰符 ) { AnimatedVisibility( visible = isVisible, enter = slideInHorizontally(), exit = slideOutHorizontally(), ) { Box( modifier = Modifier .width(100.dp) .height(16.dp) .background(Color.Red.copy(alpha = 0.5F)) ) } }
方案二:自定义动画偏移范围,限制在父布局内部
如果不想裁剪,希望动画全程在父布局可视范围内进行,可以自定义slideInHorizontally和slideOutHorizontally的偏移参数,让动画的起始/结束位置不超出父布局边界:
var isVisible by remember { mutableStateOf(true) } Button(onClick = { isVisible = !isVisible }) { Text("Click") } Box( modifier = Modifier .width(300.dp) .height(16.dp) .background(Color.Blue.copy(alpha = 0.5F)) ) { AnimatedVisibility( visible = isVisible, // 滑入时从父布局右侧边缘(自身宽度对应的位置)启动动画 enter = slideInHorizontally(initialOffsetX = { fullWidth -> fullWidth - it.width }), // 滑出时停在父布局右侧边缘,而非完全滑出父布局 exit = slideOutHorizontally(targetOffsetX = { fullWidth -> fullWidth - it.width }), ) { Box( modifier = Modifier .width(100.dp) .height(16.dp) .background(Color.Red.copy(alpha = 0.5F)) ) } }
这里的it指代动画目标组件(内层Box)的尺寸,通过fullWidth - it.width计算偏移量,让内层Box始终在父布局的宽度范围内移动,不会超出边界。
内容的提问来源于stack exchange,提问作者cchman
相关产品推荐
相关产品推荐

