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

Jetpack Compose启动其他Activity时如何实现图标动画?

在Jetpack Compose中实现启动应用时的图标动画

你可以通过在Compose中先给应用图标添加点击过渡动画,再触发Activity启动逻辑的方式,实现启动应用时的图标动画效果。以下是两种常见的实现思路:

一、图标缩放消失动画

先让图标在点击后逐渐缩放至透明消失,再启动目标应用,和系统的ScaleUp动画形成连贯效果:

var isLaunching by remember { mutableStateOf(false) }
// 缩放动画状态
val scale by animateFloatAsState(
    targetValue = if (isLaunching) 0f else 1f,
    animationSpec = tween(durationMillis = 200)
)
// 透明度动画状态
val alpha by animateFloatAsState(
    targetValue = if (isLaunching) 0f else 1f,
    animationSpec = tween(durationMillis = 200)
)

// 应用图标组件
Icon(
    painter = painterResource(id = appIconRes), // 替换为你的应用图标资源
    contentDescription = appName,
    modifier = Modifier
        .scale(scale)
        .alpha(alpha)
        .clickable {
            isLaunching = true // 触发动画
        }
)

// 动画结束后启动应用
LaunchedEffect(isLaunching) {
    if (isLaunching) {
        delay(200) // 等待动画执行完毕
        val centerX = position.x.toInt() + 24
        val centerY = position.y.toInt() + 24
        val options = ActivityOptions.makeScaleUpAnimation(
            activity?.window?.decorView,
            centerX, centerY, 0, 0
        )
        context.startActivity(intent, options.toBundle())
        isLaunching = false // 重置状态
    }
}

二、图标飞至屏幕中心动画

模拟原生启动器的效果:点击后图标移动到屏幕中心并缩小,再启动应用,衔接系统动画:

var isLaunching by remember { mutableStateOf(false) }
val screenConfig = LocalConfiguration.current
// 计算屏幕中心位置(对应图标中心)
val targetOffset = Offset(
    (screenConfig.screenWidthDp / 2 - 24).dp.toPx(),
    (screenConfig.screenHeightDp / 2 - 24).dp.toPx()
)
// 位移动画状态
val offset by animateOffsetAsState(
    targetValue = if (isLaunching) targetOffset else position,
    animationSpec = tween(durationMillis = 300, easing = FastOutSlowInEasing)
)
// 缩放动画状态
val scale by animateFloatAsState(
    targetValue = if (isLaunching) 0.3f else 1f,
    animationSpec = tween(durationMillis = 300, easing = FastOutSlowInEasing)
)

// 应用图标组件
Icon(
    painter = painterResource(id = appIconRes),
    contentDescription = appName,
    modifier = Modifier
        .offset { IntOffset(offset.x.toInt(), offset.y.toInt()) }
        .scale(scale)
        .clickable {
            isLaunching = true
        }
)

// 动画结束后启动应用
LaunchedEffect(isLaunching) {
    if (isLaunching) {
        delay(300)
        val centerX = targetOffset.x.toInt() + 24
        val centerY = targetOffset.y.toInt() + 24
        val options = ActivityOptions.makeScaleUpAnimation(
            activity?.window?.decorView,
            centerX, centerY, 0, 0
        )
        context.startActivity(intent, options.toBundle())
        isLaunching = false
    }
}

注意事项

  • 可以根据需求调整动画时长和缓动曲线,建议和系统默认动画时长(约200ms)匹配,让衔接更自然。
  • 如果需要更复杂的动画效果,可以结合AnimatedContent或自定义Transition实现。

内容的提问来源于stack exchange,提问作者Osanosa

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 04:50:04