Home > Software design >  How to add CountDownTimer to a ViewModel Kotlin?
How to add CountDownTimer to a ViewModel Kotlin?

Time:05-24

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