Transformations.map takes the input of one LiveData, applies a transformation (a function), and outputs another LiveData.
class MyViewModel : ViewModel() {
companion object {
private const val DONE = 0L
private const val ONE_SECOND = 1000L
private const val COUNTDOWN_TIME = 6000L
}
// Timer value
private val _currentTime = MutableLiveData<Long>()
val currentTime: LiveData<Long>
get() = _currentTime
val currentTimeString = Transformations.map(currentTime,{time -> // This takes in the current timer value and applies a time format before outputting it. Because it is a MutableLiveData it can be observed in a layout xml via data binding
DateUtils.formatElapsedTime(time)
})
private val timer: CountDownTimer
init {
timer = object : CountDownTimer(COUNTDOWN_TIME, ONE_SECOND) {
override fun onTick(millisUntilFinished: Long) {
_currentTime.value = millisUntilFinished/ ONE_SECOND
}
override fun onFinish() {
_currentTime.value = DONE
_eventGameFinish.value = true
}
}
timer.start()
}
}
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">
<data>
<variable
name="myViewModel"
type="com.example.android.myapp.MyViewModel" />
</data>
<TextView
android:id="@+id/timer_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{myViewModel.currentTimeString}" /> // Call the LiveData from the ViewModel
</layout>
For more complex operations you may need to use a SwitchMap or MediatorLiveData. Allows manipulation and combination of more than one LiveData.
