Jonas.S.
Jonas.S.

Reputation: 317

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

Upvotes: 1

Views: 2610

Answers (2)

Tenfour04
Tenfour04

Reputation: 93629

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

Upvotes: 1

Jonas.S.
Jonas.S.

Reputation: 317

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

Upvotes: 1

Related Questions