[英]How to recompose every minute in Jetpack Compose?
我想在我的組合中顯示一個倒計時的計時器,但我不知道如何實現這一點。
我正在考慮將延遲/超時設置一分鍾並以這種方式觸發重組,但我不確定這是否是正確的思考方式。
@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")
}
我的目標是讓文本每分鍾更新一次。 我怎樣才能做到這一點?
將分鍾數存儲為 state。
還要確保清理DisposableEffect
中的postDelayed
回調,以防止沖突延遲和 memory 泄漏。
我已將此邏輯移至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")
}
您可以將ViewModel
與CountDownTimer
class 一起使用。
就像是:
val countTimeViewModel : CountTimeViewModel = viewModel()
val minutes = countTimeViewModel.minutes.observeAsState(60)
Button( onClick={
countTimeViewModel.onStartClicked(60000*60) }
){
Text("Start")
}
Text(""+minutes.value)
和:
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.