Jetpack Compose 动画AnimatedContent

在 Jetpack Compose 中,AnimatedContent 是 Crossfade 的"终极进阶版"。如果说 Crossfade 只能做简单的交叉淡入淡出,那么 AnimatedContent 则允许你为不同内容或状态之间的切换定制极其丰富的入场(Enter)与出场(Exit)动画组合。

它非常适合用于数字计数器滚动、多步骤引导页(Wizard)切换、或者带有方向感的 Tab 页面切换。

一、 核心作用与特点

  1. 灵活的入场与出场组合 (transitionSpec)
    你可以根据"旧状态"与"新状态"的变化关系(比如数字变大还是变小、向左切还是向右切),动态决定是让新内容从上方滑入、下方滑入,还是配合缩放和透明度渐变。
  2. 自动容器尺寸动画 (SizeTransform)
    当切换前后的两个布局组件尺寸大小不一致时,AnimatedContent 能够自动、平滑地过渡外层容器的宽高,而不会产生突兀的瞬间跳变。
  3. 基于状态驱动
    和 Crossfade 类似,它接受一个 targetState。只要这个状态发生变化,它就会自动卸载旧内容、渲染新内容并播放配置好的过渡动画。

二、 典型使用示例(带方向感知的计数器)

以下代码展示了如何使用 AnimatedContent 实现一个数字计数器:当数字增大时新数字从下方滑入,减小时从上方滑入:

复制代码
@Composable
fun AnimatedCounterDemo() {
    var count by remember { mutableStateOf(0) }

    Column(
        modifier = Modifier.padding(16.dp),
        horizontalAlignment = Alignment.CenterHorizontally
    ) {
        // 控制按钮
        Row(verticalAlignment = Alignment.CenterVertically) {
            Button(onClick = { count-- }) { Text("- 减少") }
            Spacer(modifier = Modifier.width(16.dp))
            Button(onClick = { count++ }) { Text("+ 增加") }
        }

        Spacer(modifier = Modifier.height(24.dp))

        // 使用 AnimatedContent 处理内容切换
        AnimatedContent(
            targetState = count,
            transitionSpec = {
                // 根据数值大小判断动画方向
                if (targetState > initialState) {
                    // 变大:新内容从下方滑入并淡入,旧内容向上方滑出并淡出
                    (slideInVertically { height -> height } + fadeIn()) togetherWith
                            (slideOutVertically { height -> -height } + fadeOut())
                } else {
                    // 变小:新内容从上方滑入并淡入,旧内容向下方滑出并淡出
                    (slideInVertically { height -> -height } + fadeIn()) togetherWith
                            (slideOutVertically { height -> height } + fadeOut())
                }.using(
                    SizeTransform(clip = false) // 允许动画过程中超出裁剪区域
                )
            },
            label = "CounterAnimation"
        ) { targetCount ->
            // 根据 targetCount 渲染对应的内容
            Text(
                text = "$targetCount",
                fontSize = 48.sp,
                fontWeight = FontWeight.Bold,
                color = Color.Blue
            )
        }
    }
}
相关推荐
美狐美颜SDK开放平台12 小时前
准备开发直播APP?视频美颜SDK接入前的十项检查清单
android·ios·音视频·直播美颜sdk·视频美颜sdk
传奇开心果编程12 小时前
【Jetpack Compose娓娓道来】第26课:Repository模式与数据层设计——数据的唯一入口
android·移动开发·1024程序员节·jetpack compose·编程语言理论·编程框架·声明式ui
三少爷的鞋16 小时前
Kotlin 协程,重点就在「协」这个字上
android·kotlin
好的佩奇17 小时前
Dart 之模式
android·flutter·dart
淡淡的香烟19 小时前
Flutter实现多语言切换
android·flutter·1024程序员节
AIsoft_868920 小时前
手机视频转文字工具清单:哪些APP支持录屏识别
android·音视频
_祝你今天愉快1 天前
Paint Cavans高级绘制:[一]Paint画笔高级应用
android
@zulnger1 天前
安卓进行稳定性测试
android·appium·1024程序员节
不吃凉粉1 天前
android 副屏连接
android