Search code examples
androidkotlinviewmodel

How to add CountDownTimer to a ViewModel Kotlin?


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()
        })
    }
}

Solution

  • 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)
            }
        }
    }