Jetpack Compose动画实现指南

一、基础动画实现

1. 渐显/渐隐动画

var visible by remember { mutableStateOf(true) }
val alpha by animateFloatAsState(
    targetValue = if (visible) 1f else 0f,
    animationSpec = tween(durationMillis = 300)
)

Box(
    Modifier
        .alpha(alpha)
        .background(Color.Blue)
        .size(100.dp)
)

2. 尺寸变化动画

var expanded by remember { mutableStateOf(false) }
val size by animateDpAsState(
    targetValue = if (expanded) 200.dp else 100.dp,
    animationSpec = spring(stiffness = Spring.StiffnessLow)
)

Box(
    Modifier
        .size(size)
        .background(MaterialTheme.colors.primary)
        .clickable { expanded = !expanded }
)

二、过渡动画

1. 多属性组合动画

val transition = updateTransition(targetState = expanded)
val size by transition.animateDp { if (it) 200.dp else 100.dp }
val color by transition.animateColor { if (it) Color.Red else Color.Blue }

Box(
    Modifier
        .size(size)
        .background(color)
)

2. 可见性动画

var visible by remember { mutableStateOf(true) }

AnimatedVisibility(
    visible = visible,
    enter = fadeIn() + expandVertically(),
    exit = shrinkHorizontally() + fadeOut()
) {
    Box(Modifier.size(100.dp).background(Color.Green))
}

三、手势驱动动画

拖动释放动画

val offset = remember { Animatable(Offset(0f, 0f), Offset.VectorConverter) }

Box(
    Modifier
        .offset { offset.value.toIntOffset() }
        .pointerInput(Unit) {
            detectDragGestures { _, dragAmount ->
                launch {
                    offset.snapTo(offset.value + dragAmount)
                }
            }
        }
        .size(100.dp)
        .background(Color.Magenta)
)

四、高级动画技巧

1. 无限循环动画

val infiniteTransition = rememberInfiniteTransition()
val scale by infiniteTransition.animateFloat(
    initialValue = 1f,
    targetValue = 1.5f,
    animationSpec = infiniteRepeatable(
        animation = tween(1000),
        repeatMode = RepeatMode.Reverse
    )
)

Box(
    Modifier
        .size(100.dp)
        .graphicsLayer(scaleX = scale, scaleY = scale)
        .background(Color.Cyan)
)

2. 矢量路径动画

val path = Path().apply {
    moveTo(100f, 100f)
    quadraticTo(300f, 200f, 500f, 100f)
}

val animatable = remember { Animatable(0f, Float.VectorConverter) }
LaunchedEffect(Unit) {
    animatable.animateTo(1f, animationSpec = tween(2000))
}

Box(
    Modifier
        .graphicsLayer {
            val point = path.getPoint(animatable.value)
            translationX = point.x
            translationY = point.y
        }
        .size(50.dp)
        .background(Color.Yellow)
)

五、最佳实践

  1. 性能优化

    • 优先使用 remember 缓存动画对象
    • 对复杂动画使用 derivedStateOf
    • 避免在动画过程中触发重组
  2. 动画协调

val transition = updateTransition(checked)
val borderWidth by transition.animateDp { if (it) 4.dp else 2.dp }
val elevation by transition.animateDp { if (it) 8.dp else 2.dp }

Surface(
    modifier = Modifier
        .border(borderWidth, Color.Red, CircleShape)
        .elevation(elevation),
    shape = CircleShape
) { /* ... */ }

六、调试工具

  1. 使用 Modifier.drawWithContent { } 可视化动画进度
  2. 开启布局检查器查看动画参数实时变化
  3. 使用 debugInspectorInfo 添加调试信息

Jetpack Compose 的声明式动画系统通过智能重组机制,可以自动处理动画的生命周期和状态管理。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值