jetpack compose中的CountDownTimer

问题描述 投票:0回答:5

我正在使用以下代码在 jetpack 中尝试 CountDownTimer 组合

@Composable
fun Timer() {
    val millisInFuture: Long = 10 * 1000 // TODO: get actual value

    val timeData = remember {
        mutableStateOf(millisInFuture)
    }

    val countDownTimer =
        object : CountDownTimer(millisInFuture, 1000) {
            override fun onTick(millisUntilFinished: Long) {
                Log.d("TAG", "onTick: ")
                timeData.value = millisInFuture
            }

            override fun onFinish() {
               
            }
        }
    
    DisposableEffect(key1 = "key") {
        countDownTimer.start()
        onDispose {
            countDownTimer.cancel()
        }
    }

    Text(
        text = timeData.value.toString()
    )
}

在 logcat 中,我可以看到计时器正在滴答作响,但 UI 没有更新。 请解释为什么改变状态变量的值会发生重组。

android android-jetpack-compose
5个回答
4
投票

简单的倒数计时器只为第二个

var timer by remember { mutableStateOf(durationSeconds) }
LaunchedEffect(key1 = timer) {
    if (timer > 0) {
        delay(1_000)
        timer -= 1
    }
}


Text(
    text = timer.toString()
) 

3
投票

嗯,在 CountDownTimer 中,您应该设置 millisUntilFinished,而不是设置 millisInFuture。该变量保存更新后的值,millisInFuture 永远不会改变

timeData.value = millisUntilFinished

3
投票

您可以尝试使用此代码来实现倒计时器:

val time = (timerDate.time).minus(Calendar.getInstance().timeInMillis)
var timer by remember { mutableStateOf(time) }
  LaunchedEffect(key1 = timer) {
      if (timer > 0) {
          delay(1000L)
          timer -= 1000L
       }
     }
  val secMilSec: Long = 1000
  val minMilSec = 60 * secMilSec
  val hourMilSec = 60 * minMilSec
  val dayMilSec = 24 * hourMilSec
  val hours = (time % dayMilSec / hourMilSec).toInt()
  val minutes = (time % dayMilSec % hourMilSec / minMilSec).toInt()
  val seconds = (time % dayMilSec % hourMilSec % minMilSec / secMilSec).toInt()

Text(text = String.format("%02d:%02d:%02d", hours, minutes, seconds))

1
投票

最简单的解决方案是在几秒钟内进行类似于

countDownTimer
的延迟,如下所示:

@Composable
private fun Timer(
    waitingTime: Long = WAITING_TIME_MILLIS,
    onFinish: () -> Unit
) = LaunchedEffect(waitingTime) {
    delay(waitingTime)
    onFinish()
}

0
投票

仅当可组合函数参数或可组合本身内部

State<T>
的值更改(如
mutableStateOf()
mutableStateListOf()
)发生状态更改时,才可组合。就您而言,您还没有启动
countDownTimer
本身。尝试在
countDownTimer.start()
内调用
DisposableEffect
。其次,您将 timeData 设置为错误的值,尝试使用
millisUntilFinished

设置它
© www.soinside.com 2019 - 2024. All rights reserved.