Jetpack Compose 动画Crossfade

在 Jetpack Compose 中,Crossfade 是一个专为不同内容或布局之间的交叉淡入淡出(Cross-fade)切换设计的轻量级动画 API。

当你的界面需要在两个(或多个)不同的 Composable 状态之间切换,并且希望旧内容淡出、新内容淡入时,Crossfade 可以用极少的代码实现极其平滑的视觉过渡。

一、 核心作用与特点

  1. 内容平滑交叉淡入淡出
    它会自动处理旧内容的淡出(Alpha 从 1 降到 0)和新内容的淡入(Alpha 从 0 升到 1),两者的切换是同时进行且无缝衔接的。
  2. 基于状态 Key 的驱动
    你只需传入一个目标状态(比如一个枚举值、布尔值或整型 ID)。当这个 Key 发生变化时,Crossfade 会自动触发内部的淡入淡出动画。
  3. 替代复杂的手动 Visibility 控制
    相比于写多个 AnimatedVisibility 去控制互斥显示,Crossfade 专门针对"二选一"或"多选一"的内容替换场景进行了封装,代码更加简洁。

二、 典型使用示例

以下代码展示了如何使用 Crossfade 实现底部 Tab 切换或视图状态切换(例如在"首页"和"个人中心"之间切换):

复制代码
enum class ScreenType {
    Home, Profile
}

@Composable
fun CrossfadeDemo() {
    // 1. 定义控制当前显示内容的视图状态
    var currentScreen by remember { mutableStateOf(ScreenType.Home) }

    Column(
        modifier = Modifier.padding(16.dp),
        horizontalAlignment = Alignment.CenterHorizontally
    ) {
        // 切换按钮
        Row(modifier = Modifier.padding(bottom = 16.dp)) {
            Button(onClick = { currentScreen = ScreenType.Home }) {
                Text("首页")
            }
            Spacer(modifier = Modifier.width(8.dp))
            Button(onClick = { currentScreen = ScreenType.Profile }) {
                Text("个人中心")
            }
        }

        // 2. 使用 Crossfade 包裹内容切换区域
        Crossfade(
            targetState = currentScreen,
            animationSpec = tween(durationMillis = 400),
            label = "ScreenCrossfade"
        ) { screen ->
            // 3. 根据不同的 targetState 渲染对应的 UI
            when (screen) {
                ScreenType.Home -> {
                    Box(
                        modifier = Modifier
                            .fillMaxWidth()
                            .height(150.dp)
                            .background(Color.Blue, RoundedCornerShape(8.dp)),
                        contentAlignment = Alignment.Center
                    ) {
                        Text("🏠 欢迎来到首页内容", color = Color.White, fontSize = 18.sp)
                    }
                }
                ScreenType.Profile -> {
                    Box(
                        modifier = Modifier
                            .fillMaxWidth()
                            .height(150.dp)
                            .background(Color.Magenta, RoundedCornerShape(8.dp)),
                        contentAlignment = Alignment.Center
                    ) {
                        Text("👤 个人中心与设置页面", color = Color.White, fontSize = 18.sp)
                    }
                }
            }
        }
    }
}
相关推荐
Gracker1 小时前
AIW:从系统机制到性能排查,一本可以对照源码的 Android 电子书
android
三少爷的鞋1 小时前
代码越来越便宜,判断力越来越贵:AI 时代的 Android 架构与协程避坑指南
android
Gracker3 小时前
SmartPerfetto 1.19.0:换过分析引擎之后,这次更新了什么
android
HQL_seven7 小时前
【Android】BroadcastReceiver 详解
android
_祝你今天愉快8 小时前
Paint Cavans高级绘制:[二] Paint-滤镜,XFERMODE
android
小乖写代码8 小时前
字段获取代码(Android) · Android Input Examples
android·whatsapp·账号注册
booboosui8 小时前
停一个活只有杀进程:界面上少了「说点要求」
android
传奇开心果编程11 小时前
【Flutter踩坑排雷】第28课:平台目录缺失与修复坑|`flutter create` 的“重建”与“覆盖”边界
android·flutter·ios·移动开发·跨平台·dart·声明式ui
longxibo20 小时前
【AIBIZ低代码平台:能长出业务系统的平台】
android·低代码·rxjava
AI_Gump1 天前
Harness篇|DeepSeek Harness 上手机:五条安卓移植路线与 App 内 Linux 拆解
android·linux·人工智能·智能手机·deepseek