I am trying to add a CountDownTimer to a ViewModel to be able to rotate a screen without losing data in this case a countt timer. In my code, I don't know how to return countdowntimer value from a ViewModel?
My code:
class MainActivityViewModel: ViewModel() {
val countt = MutableLiveData<Long>()
private val timer = object :CountDownTimer(30000, 2000){
override fun onTick(millisUntilFinished: Long) {
countt.value = millisUntilFinished
}
override fun onFinish() {
}
}
timer.start()
}
class MainActivity : AppCompatActivity() {
private lateinit var binding: ActivityMainBinding
private lateinit var viewModel: MainActivityViewModel
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = DataBindingUtil.setContentView(this, R.layout.activity_main)
viewModel = ViewModelProvider(this)[MainActivityViewModel::class.java]
viewModel.countt.observe(this, Observer {
binding.countText.text = it.toString()
})
}
}
CodePudding user response:
Now it works:
class MainActivityViewModel: ViewModel() {
val countt = MutableLiveData<Long>()
private fun timer(){
val timer = object :CountDownTimer(300000, 1000){
override fun onTick(millisUntilFinished: Long) {
countt.value = millisUntilFinished / 1000
}
override fun onFinish() {
}
}
timer.start()
}
val countValue: MutableLiveData<Long>
get() = countt
init {
timer()
}
}
CodePudding user response:
FYI, here's an easier way to do this using the Jetpack liveData
coroutine builder, if you don't need super precise intervals (since this doesn't account for the code execution time):
class MainActivityViewModel: ViewModel() {
val countt = liveData {
for (value in 300 downTo 0) {
emit(value)
delay(1000)
}
}
}
If you did need it very precise, I guess you'd have to update the delay amount to be more accurate, so it gets a little more messy:
class MainActivityViewModel: ViewModel() {
val countt = liveData {
val endTime = System.currentTimeMillis() 300 * 1000
for (value in 300 downTo 0) {
delay(endTime - value * 1000 - System.currentTimeMillis())
emit(value)
}
}
}