【问题标题】:Is it ok to pass the ViewModel to the RecyclerView (No DataBinding)?可以将 ViewModel 传递给 RecyclerView(无 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 一直存在,我的活动已经完成,所以没有泄漏内存,对吧?

【问题讨论】:

    标签: android mvvm android-recyclerview onclicklistener android-viewmodel


    【解决方案1】:

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

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

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

    1. 开始使用 DataBinding。
    2. 基本上执行 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,当然。

    【讨论】:

    • 抱歉我编辑了那部分含糊不清的问题。很好,我没想到会这样,这很有趣?,谢谢你的帮助!
    猜你喜欢
    • 2018-12-23
    • 1970-01-01
    • 2020-02-18
    • 2014-06-08
    • 2021-06-11
    • 1970-01-01
    • 2017-09-17
    • 2013-10-08
    • 1970-01-01
    相关资源
    最近更新 更多