一、viewModel+自定义接口的方式实现
注意点:viewModel中不要传入context的相关内容,容易内存泄露,如果需要上下文对象,可以继承ViewModel类的子类AndroidViewModel类,而不是ViewModel类.
class TimeViewModel:ViewModel() {
private lateinit var timer:Timer
private var currentSecond=0
fun startTimer(){
timer=Timer()
currentSecond=0
val timerTask=object :TimerTask(){
override fun run() {
currentSecond++
if (onTimeChangeListener!=null){
onTimeChangeListener.onTimeChanged(currentSecond)
}
}
}
timer.schedule(timerTask,1000,1000)
}
interface OnTimeChangeListener{
fun onTimeChanged(second:Int)
}
private lateinit var onTimeChangeListener: OnTimeChangeListener
fun setOnTimeChangeListener(onTimeChangeListener: OnTimeChangeListener){
this.onTimeChangeListener=onTimeChangeListener
}
override fun onCleared() {
super.onCleared()
timer.cancel()
}
}
activity或者fragment中的调用:
private fun timeListener(){
val timeViewModel= ViewModelProvider(this)[TimeViewModel::class.java]
timeViewModel.setOnTimeChangeListener(object :TimeViewModel.OnTimeChangeListener{
override fun onTimeChanged(second: Int) {
activity?.runOnUiThread {
binding.textviewTime.text="TIME:$second"
}
}
})
timeViewModel.startTimer()
}
二、viewModel+LiveData的实现
注意区分一下setValue:只能用于主线程,
postValue:可以用在主线程,也可以子线程
class TimeWithLivedataViewModel:ViewModel() {
private lateinit var timer: Timer
private var currentSecond=0
private var second:MutableLiveData<Int> = MutableLiveData()
fun getCurrentSecond():MutableLiveData<Int>{
return second
}
fun startTimer(){
timer=Timer()
currentSecond=0
val timerTask=object :TimerTask(){
override fun run() {
currentSecond++
second.postValue(currentSecond)
}
}
timer.schedule(timerTask,1000,1000)
}
}
liveData.observe()方法对Livedata包装的数据进行观察,反过来,当我们需要修改livedata包装的数据的时候,可以通过postValue/setValue来完成,这个方式只是会插入当前的数据中,不会重新开始执行,如果想重新开始,则需要修改viewmodel中的初始值.
private fun timeLiveData(){
val timeWithLivedataViewModel=ViewModelProvider(this)[TimeWithLivedataViewModel::class.java]
val liveData=timeWithLivedataViewModel.getCurrentSecond()
liveData.observe(requireActivity()){second->
binding.textviewTime.text="TIME:$second"
}
binding.btnTime.setOnClickListener {
liveData.postValue(0)
// timeWithLivedataViewModel.currentSecond=0
}
timeWithLivedataViewModel.startTimer()
}
此外,livedata的observe方法的最后一行代码可以看出,livedata可以感知页面的生命周期,获取页面的状态
截屏2023-03-10 15.51.30.png