Android 如何重新组合Jetpack中的每一分钟?
我想在我的composable中显示一个计时器倒计时,但我不确定如何实现这一点 我想设置一分钟的延迟/超时,然后以这种方式触发一个重新组合,但我不确定这是否是正确的思考方式Android 如何重新组合Jetpack中的每一分钟?,android,kotlin,android-jetpack,android-jetpack-compose,Android,Kotlin,Android Jetpack,Android Jetpack Compose,我想在我的composable中显示一个计时器倒计时,但我不确定如何实现这一点 我想设置一分钟的延迟/超时,然后以这种方式触发一个重新组合,但我不确定这是否是正确的思考方式 @Composable fun Countdown(completedAt: Date) { val minutesLeft = ceil((completedAt.time - Date().time) / 60_000.0).toInt() Handler(Looper.getMainLooper())
@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")
}
我的目标是让文本每分钟都随着新的时间而更新。如何执行此操作?将分钟数存储为状态 还要确保清理内部的
postDelayed
回调,以防止冲突延迟和内存泄漏
我已将此逻辑移动到一个minutesleet
可组合函数,以便可以重用
@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()
}
用法
将分钟数存储为状态 还要确保清理内部的
postDelayed
回调,以防止冲突延迟和内存泄漏
我已将此逻辑移动到一个minutesleet
可组合函数,以便可以重用
@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()
}
用法
您可以在类中使用
ViewModel
比如:
val countTimeViewModel : CountTimeViewModel = viewModel()
val minutes = countTimeViewModel.minutes.observeAsState(60)
Button( onClick={
countTimeViewModel.onStartClicked(60000*60) }
){
Text("Start")
}
Text(""+minutes.value)
与:
class CountTimeViewModel:ViewModel(){
专用变量计时器:倒计时?=null
private val_minutes=MutableLiveData(totalTime)
val分钟数:LiveData get()=\u分钟
专用var总时间:长=0L
乐趣开始计数(){
定时器=对象:倒计时器(总时间,60000){
覆盖趣味点击(毫秒:长){
//会议记录
val minutes=(毫秒/毫秒/秒/秒/分钟%秒/分钟)。toInt()
_分钟。postValue(分钟)
}
重写函数onFinish(){
//…倒计时完成
}
}
}
开始点击时的乐趣(总时间:长){
this.totalTime=总时间
开始计数()
计时器?.start()
}
覆盖有趣的onCleared(){
super.onCleared()
计时器?.cancel()
}
伴星{
以分钟为单位的常数=60
常数值毫秒单位秒=1000
}
}
您可以在类中使用视图模型
比如:
val countTimeViewModel : CountTimeViewModel = viewModel()
val minutes = countTimeViewModel.minutes.observeAsState(60)
Button( onClick={
countTimeViewModel.onStartClicked(60000*60) }
){
Text("Start")
}
Text(""+minutes.value)
与:
class CountTimeViewModel:ViewModel(){
专用变量计时器:倒计时?=null
private val_minutes=MutableLiveData(totalTime)
val分钟数:LiveData get()=\u分钟
专用var总时间:长=0L
乐趣开始计数(){
定时器=对象:倒计时器(总时间,60000){
覆盖趣味点击(毫秒:长){
//会议记录
val minutes=(毫秒/毫秒/秒/秒/分钟%秒/分钟)。toInt()
_分钟。postValue(分钟)
}
重写函数onFinish(){
//…倒计时完成
}
}
}
开始点击时的乐趣(总时间:长){
this.totalTime=总时间
开始计数()
计时器?.start()
}
覆盖有趣的onCleared(){
super.onCleared()
计时器?.cancel()
}
伴星{
以分钟为单位的常数=60
常数值毫秒单位秒=1000
}
}
将其置于可变状态并更新循环中的状态。将其置于可变状态并更新循环中的状态。次要优化:p可以使用val
而不是var minutes
两个问题:1)如何处理问题中提到的completedAt
参数?2) 为什么这比使用Handler
更好?@DuncanLuk在viemodel
layer@DuncanLuk我已经用视图模型更新了答案。completedAt
代码应该在onFinish
函数的ViewModel中移动。@SantanuSur感谢反馈小优化:p可以使用val
而不是var minutes
两个问题:1)这如何处理问题中提到的completedAt
参数?2) 为什么这比使用Handler
更好?@DuncanLuk在viemodel
layer@DuncanLuk我已经用视图模型更新了答案。completedAt
代码应该在onFinish
函数的ViewModel中移动。@SantanuSur感谢您的反馈