[英]How to recompose every minute in Jetpack Compose?
I would like to show a timer counting down in my composable, but I am not sure how to achieve this.我想在我的组合中显示一个倒计时的计时器,但我不知道如何实现这一点。
I was thinking to set a delay/timeout for a minute and trigger a recompose that way, but I am not sure if that's the right way to think about it.我正在考虑将延迟/超时设置一分钟并以这种方式触发重组,但我不确定这是否是正确的思考方式。
@Composable
fun Countdown(completedAt: Date) {
val minutesLeft = ceil((completedAt.time - Date().time) / 60_000.0).toInt()
Handler(Looper.getMainLooper()).postDelayed({
// TODO: Recompose
}, 60_000)
Text(text = "$minutesLeft minutes until completed")
}
My goal is for the text to update every minute with the new time.我的目标是让文本每分钟更新一次。 How can I do this?
我怎样才能做到这一点?
Store the amount of minutes as state.将分钟数存储为 state。
Also make sure to clean up the postDelayed
callback inside a DisposableEffect
to prevent conflicting delays and memory leaks.还要确保清理
DisposableEffect
中的postDelayed
回调,以防止冲突延迟和 memory 泄漏。
I have moved this logic to a minutesLeft
composable function so it can be reused.我已将此逻辑移至
minutesLeft
可组合 function 以便可以重复使用。
@Composable
fun minutesLeft(until: Date): Int {
var value by remember { mutableStateOf(getMinutesLeft(until)) }
DisposableEffect(Unit) {
val handler = Handler(Looper.getMainLooper())
val runnable = {
value = getMinutesLeft(until)
}
handler.postDelayed(runnable, 60_000)
onDispose {
handler.removeCallbacks(runnable)
}
}
return value
}
private fun getMinutesLeft(until: Date): Int {
return ceil((until.time - Date().time) / 60_000.0).toInt()
}
@Composable
fun Countdown(completedAt: Date) {
val minutes = minutesLeft(until = completedAt)
Text(text = "$minutes minutes until completed")
}
You can use a ViewModel
with the CountDownTimer
class.您可以将
ViewModel
与CountDownTimer
class 一起使用。
Something like:就像是:
val countTimeViewModel : CountTimeViewModel = viewModel()
val minutes = countTimeViewModel.minutes.observeAsState(60)
Button( onClick={
countTimeViewModel.onStartClicked(60000*60) }
){
Text("Start")
}
Text(""+minutes.value)
with:和:
class CountTimeViewModel : ViewModel() {
private var timer: CountDownTimer? = null
private val _minutes = MutableLiveData(totalTime)
val minutes: LiveData<Int> get() = _minutes
private var totalTime : Long = 0L
fun startCountDown() {
timer = object : CountDownTimer(totalTime, 60000) {
override fun onTick(millisecs: Long) {
// Minutes
val minutes = (millisecs / MSECS_IN_SEC / SECS_IN_MINUTES % SECS_IN_MINUTES).toInt()
_minutes.postValue(minutes)
}
override fun onFinish() {
//...countdown completed
}
}
}
fun onStartClicked(totalTime : Long) {
this.totalTime = totalTime
startCountDown()
timer?.start()
}
override fun onCleared() {
super.onCleared()
timer?.cancel()
}
companion object {
const val SECS_IN_MINUTES = 60
const val MSECS_IN_SEC = 1000
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.