You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.22 14:45:16