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

如何用Jetpack Compose实现计时器递减时扫角从360开始的圆弧动画

问题分析与解决方案

你的核心问题是扫角计算依赖固定的100作为分母,导致只有初始时间为100时,扫角才会从360°开始。另外代码里还有几处变量名不匹配的bug(比如countDownTimerSweepAngle、playTime都是未定义的变量),需要一并修正。

关键修复点:

  • 保存初始时间值,用当前时间与初始时间的比例计算扫角,而非固定除以100
  • 修正变量名不匹配的错误
  • 调整LaunchedEffect的触发逻辑,避免计时器重复启动

完整修正代码:

Column(
    modifier = Modifier.fillMaxSize(),
    horizontalAlignment = Alignment.CenterHorizontally,
    verticalArrangement = Arrangement.Center
) {
    // 可自定义初始时间
    val initialTime = 60
    var time by remember { mutableIntStateOf(initialTime) }
    var isTimerRunning by remember { mutableStateOf(true) }
    var sweepAngle by mutableFloatStateOf(360f)

    val animatedSweepAngle = animateFloatAsState(
        targetValue = sweepAngle,
        animationSpec = tween(durationMillis = 1000) // 匹配1秒倒计时的动画时长
    )

    // 启动计时器
    LaunchedEffect(isTimerRunning) {
        if (isTimerRunning) {
            while (time > 0) {
                delay(1000)
                time--
                // 用当前时间/初始时间的比例计算扫角,确保初始扫角始终为360°
                sweepAngle = (time.toFloat() / initialTime) * 360f
            }
            isTimerRunning = false
        }
    }

    // 显示剩余时间
    Text(
        text = time.toString(),
        fontSize = 32.sp,
        color = Color.White,
        modifier = Modifier.padding(bottom = 20.dp)
    )

    // 动画圆弧
    Box(
        modifier = Modifier
            .size(100.dp)
            .background(Color.Black)
            .drawBehind {
                drawArc(
                    color = Color.White,
                    startAngle = 90f,
                    sweepAngle = animatedSweepAngle.value,
                    useCenter = false,
                    style = Stroke(
                        width = 3.dp.toPx(),
                        cap = StrokeCap.Round
                    )
                )
            }
    )
}

说明:

  1. 初始时间保存:用initialTime定义初始倒计时时长,remember保存当前时间time的初始值为initialTime,确保比例计算的基准正确。
  2. 扫角计算逻辑:(time.toFloat() / initialTime) * 360f保证初始时time=initialTime,扫角为360°;每减少1秒,扫角按比例递减,直到时间归0时扫角为0°。
  3. 动画同步:设置animationSpec = tween(durationMillis = 1000),让扫角动画的时长与1秒倒计时的间隔匹配,过渡更平滑。
  4. 计时器逻辑优化:用isTimerRunning控制计时器启动,避免LaunchedEffect因time变化重复触发,确保计时器只运行一次。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 09:40:15