My activity has a Google\'s ViewModel that fetches some model items. These items are then transformed into adapter items of a RecyclerView. There are also many types of adapter
Although that is true that Android uses ViewModels in Android Architecture Components it does not mean that they are just part of AAC. In fact, ViewModels are one of the components of the MVVM Architecture Pattern, which is not Android only related. So ViewModel's actual purpose is not to preserve data across Android's lifecycle changes. However, because of exposing its data without having a View's reference makes it ideal for the Android specific case in which the View can be recreated without affecting to the component that holds its state (the ViewModel). Nonetheless, it has other benefits such as facilitating the Separation of Concerns among others.
It is also important to mention that your case can not be 100% compared to the ViewPager-Fragments case, as the main difference is that the ViewHolders will be recycled between items. Even if ViewPager's Fragments are destroyed and recreated, they will still represent the same Fragment with that same data. That is why they can safely bind the data provided by their already existing ViewModel
. However, in the ViewHolder
case, when it is recreated, it can be representing a totally new item, so the data its supposed ViewModel
could be providing may be incorrect, referencing the old item.
That being said you could easily make the ViewHolder
become a ViewModelStoreOwner
:
class MyViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView), ViewModelStoreOwner {
private var viewModelStore: ViewModelStore = ViewModelStore()
override fun getViewModelStore(): ViewModelStore = viewModelStore
}
This can still be useful if the data provided by the ViewModel
is the same independently of the ViewHolder
's item (shared state between all items). However, if that is not the case, then you would need to invalidate the ViewModelStore
by calling viewModelStore.clear()
and create a new ViewModel
instance probably in ViewHolder
's onViewRecycled
. You will loose the advantage of keeping the state no matter the view's lifecycle, but can sometimes still be useful as to follow Separation of Concerns.
Finally, regarding to the option of using a LiveData
instance to control the state, no matter if it is provided by a ViewHolder
's shared or specific ViewModel
or it is passed through the Adapter
, you will need a LifecycleOwner
to observe it. A better approach to using the current Fragment
or Activity
lifecycle is to just use the specific ViewHolder
's actual lifecycle, as they are actually created and destroyed, by making them implement the LifecycleOwner
interface. I created a small library which does exactly that.