Should livedata be always used in ViewModel?

Viewed 1084

It seems like recommended pattern for fields in viewmodel is:

val selected = MutableLiveData<Item>()

fun select(item: Item) {
    selected.value = item
}

(btw, is it correct that the selected field isn't private?)

But what if I don't need to subscribe to the changes in the ViewModel's field. I just need passively pull that value in another fragment.

My project details:

  • one activity and a bunch of simple fragments replacing each other with the navigation component
  • ViewModel does the business logic and carries some values from one fragment to another
  • there is one ViewModel for the activity and the fragments, don't see the point to have more than one ViewModel, as it's the same business flow
  • I'd prefer to store a value in one fragment and access it in the next one which replaces the current one instead of pass it into a bundle and retrieve again and again manually in each fragment

ViewModel:

private var amount = 0
fun setAmount(value: Int) { amount = value}
fun getAmount() = amount

Fragment1:

bnd.button10.setOnClickListener { viewModel.setAmount(10) }

Fragment2:

if(viewModel.getAmount() < 20) { bnd.textView.text = "less than 20" }

Is this would be a valid approach? Or there is a better one? Or should I just use LiveData or Flow?

Maybe I should use SavedStateHandle? Is it injectable in ViewModel?

1 Answers

To answer your question,

No, It is not mandatory to use LiveData always inside ViewModel, it is just an observable pattern to inform the caller about updates in data. If you have something which won't be changed frequently and can be accessed by its instance. You can completely ignore wrapping it inside LiveData. And anyways ViewModel instance will be preserved and so are values inside it.

And regarding private field, MutableLiveData should never be exposed outside the class, as the data flow is always from VM -> View which is beauty of MVVM pattern

private val selected = MutableLiveData<Item>()
val selectedLiveData : LiveData<Item>
    get() = selected

fun select(item: Item) {
    selected.value = item
}
Related