Android jetpack 编写倒计时动画

Vah*_*kin 3 android kotlin jetpack android-jetpack android-jetpack-compose

是否可以使用 Jetpack Compose 制作类似 gif 的动画?

在此输入图像描述

Thr*_*ian 10

其中一种方法是使用 Animatables 来依次动画缩放和 alpha。

在此输入图像描述

创建一个包含 2 个动画的类

class AnimatedCountdownTimer(
    private val coroutineScope: CoroutineScope
) {

    private val animatableScale = Animatable(1f)
    private val animatableAlpha = Animatable(1f)

    val scale: Float
        get() = animatableScale.value

    val alpha: Float
        get() = animatableAlpha.value

    fun start(initialValue: Int, endValue: Int, onChange: (Int) -> Unit) {

        var value = initialValue

        coroutineScope.launch {
            while (value > endValue - 1) {
                onChange(value)
                animatableScale.snapTo(1f)
                animatableAlpha.snapTo(1f)
                animatableScale.animateTo(2f, animationSpec = tween(750))
                animatableAlpha.animateTo(0f, animationSpec = tween(250))
                value--

            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

并将其用作

@Preview
@Composable
fun TimerTest() {


    var timer by remember {
        mutableStateOf(5)
    }

    val coroutineScope = rememberCoroutineScope()

    val animatedCountdownTimer = remember {
        AnimatedCountdownTimer(coroutineScope)
    }

    Column(
        modifier = Modifier.fillMaxSize().padding(16.dp),
        horizontalAlignment = Alignment.CenterHorizontally
    ) {
        Text(
            modifier = Modifier.graphicsLayer {
                scaleX = animatedCountdownTimer.scale
                scaleY = animatedCountdownTimer.scale
                alpha = animatedCountdownTimer.alpha
            },
            text = "$timer",
            fontSize = 120.sp,
            fontWeight = FontWeight.Bold,
            color = Color.Gray
        )
        Spacer(Modifier.height(20.dp))
        Button(
            modifier = Modifier.fillMaxWidth(),
            onClick = {
                animatedCountdownTimer.start(5, 0) {
                    timer = it
                }
            }
        ) {
            Text("Start")
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

如果您不想在动画结束后缩放到 1f,只需添加 if 块即可保持缩放比例。任何参数都可以轻松定制持续时间或最大范围。

如果你想保留最后一个数字,你可以这样使用它

  coroutineScope.launch {
        while (value > endValue - 1) {
            onChange(value)
            animatableScale.snapTo(1f)
            animatableAlpha.snapTo(1f)
            animatableScale.animateTo(2f, animationSpec = tween(750))
            if (value > endValue) {
                animatableAlpha.animateTo(0f, animationSpec = tween(250))
            }
            value--
        }
    }
Run Code Online (Sandbox Code Playgroud)