Reputation: 261
If I understood correctly, the ViewModel is supposed to take care of all UI related data and UI events, if so, how can I handle UI events inside RecyclerViews using ViewModel?
In the Google samples of Architecture Components they make this happen through DataBinding, they create a variable called "viewModel" in the XML of the Fragment and the same in the XML of the item and then they set the variable using the generated DataBinding class passing the ViewModel.
Currently I'm not able to use DataBinding, so what are my options?
My main idea is to pass the ViewModel to the Adapter and the ViewHolder, is that ok? ViewModel lives unitl my activity is finished, so no leaked memory, right?
Upvotes: 1
Views: 475
Reputation: 10155
If I understood correctly, the ViewModel is supposed to take care of all UI related data and UI events, if so, how can I accomplish this?
That's a very vague question.
Currently I'm not able to use DataBinding, so what are my options?
My main idea is to pass the ViewModel to the Adapter and the ViewHolder, is that ok?
Sure. You have to get that data down into the adapter and it's views somehow. You don't necessarily have to pass the ViewModel itself down to the Adapter - just create the data objects the adapter needs from the ViewModel.
For example:
class MyFragment : Fragment() {
private val viewModel = MyFragmentViewModel()
private val adapter = MyFragmentAdapter()
// Call this in response to some state change in the VM
private fun updateRecyclerView() {
// Generate a list of "item viewmodels" to represent
// each child item from the Fragment ViewModel's data state
val itemViewModels = viewModel.itemsToDisplay.map {
ItemViewModel(it)
}
adapter.item = itemViewModels
adapter.notifyDataSetChanged()
}
}
Then your Adapter and Viewholder work with ItemViewModel
s and don't know anything about the top-level view model.
fun onBindViewHolder(...) {
val itemViewModel = items[position]
val itemView = viewHolder.view
// itemViewModel has the logic for formatting / state, this is just doing a dumb asssingment (aka, what DataBinding would do for you)
itemView.textView.text = itemViewModel.text
itemView.checkbox.checked = itemViewModel.checked
itemView.setOnClickListener { itemViewModel.doSomethingOnClick() }
}
ViewModel lives unitl my activity is finished, so no leaked memory, right?
Assuming you're not doing something crazy like holding on to a Context
in the ViewModel, sure.
Upvotes: 1