可以将 ViewModel 传递给 RecyclerView(无 DataBinding)吗?

Posted

技术标签:

【中文标题】可以将 ViewModel 传递给 RecyclerView(无 DataBinding)吗?【英文标题】:Is it ok to pass the ViewModel to the RecyclerView (No DataBinding)? 【发布时间】:2021-08-22 16:35:57 【问题描述】:

如果我理解正确,ViewModel 应该负责所有与 UI 相关的数据和 UI 事件,如果是这样,我如何使用 ViewModel 处理 RecyclerViews 中的 UI 事件?

在 Google 架构组件示例中,他们通过 DataBinding 实现这一点,他们在 Fragment 的 XML 中创建一个名为“viewModel”的变量,在项目的 XML 中创建一个名为“viewModel”的变量,然后他们使用生成的 DataBinding 设置变量传递 ViewModel 的类。

目前我无法使用 DataBinding,我有什么选择?

我的主要想法是将 ViewModel 传递给 Adapter 和 ViewHolder,可以吗? ViewModel 一直存在,我的活动已经完成,所以没有泄漏内存,对吧?

【问题讨论】:

【参考方案1】:

如果我理解正确,ViewModel 应该负责所有与 UI 相关的数据和 UI 事件,如果是这样,我该如何做到这一点?

这是一个非常模糊的问题。

目前我无法使用 DataBinding,我有什么选择?

    开始使用 DataBinding。 基本上执行 DataBinding 的操作,但手动操作。这归结为为实时数据对象注册观察者,这些对象会更新 UI 以响应更改并处理视图事件(如点击侦听器)并更新 ViewModel 中的状态。

我的主要想法是将 ViewModel 传递给 Adapter 和 ViewHolder,可以吗?

当然。您必须以某种方式将该数据放入适配器和它的视图中。您不必将 ViewModel 本身向下传递给 Adapter - 只需从 ViewModel 创建适配器所需的数据对象。

例如:

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

然后你的适配器和视图持有者使用ItemViewModels 并且对***视图模型一无所知。

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 在我的活动完成后仍然存在,所以没有内存泄漏,对吧?

假设你没有做一些疯狂的事情,比如在 ViewModel 中坚持 Context,当然。

【讨论】:

抱歉我编辑了那部分含糊不清的问题。很好,我没想到会这样,这很有趣?,谢谢你的帮助!

以上是关于可以将 ViewModel 传递给 RecyclerView(无 DataBinding)吗?的主要内容,如果未能解决你的问题,请参考以下文章

为啥将 ViewModel 传递给 View 时会出现此错误?

将事件传递给 ViewModel 的最佳方式是啥?

SwiftUI 将 Int 值传递给 ViewModel

SwiftUI 将@Published viewmodel 对象值传递给@Binding

如何将editText值传递给viewModel和Livedata(Kotlin)

MVC,映射器将 ViewModel 传递给 CreateView 的问题