查看RecyclerView项目的模型

问题描述 投票:2回答:1

我的活动有一个Google的ViewModel,它可以获取一些模型项。然后将这些项目转换为RecyclerView的适配器项目。一个RecyclerView还支持许多类型的适配器项。

我想为每个这些模型对象有一个单独的视图模型对象,这样我可以将更复杂的逻辑仅封装在该“小”视图模型中。

[当前,当我有一些仅与某些适配器项有关的异步逻辑(需要在onCleared()中停止)时,我必须以某种方式通过主视图模型路由回调,以便正确地注销所有内容。

我曾考虑使用ViewModelProvider::get(key, modelClass),但我的商品随着时间的推移而变化,我找不到找到清除旧物件的好方法。

您如何在项目中处理这些情况?

编辑:要添加有关我的关注的更多信息,也许用不同的词:我希望我的“小” ViewModel能够在它代表的模型项的范围内生存。这意味着:

  • 在这些项的父项接收相同的情况下,我必须接收onCleared()回调
  • 当项目不再存在时,我必须接收onCleared()回调

编辑:请尝试将其与带有Fragments作为项目的ViewPager进行比较。每个单独的模型项都用其ViewModel表示为片段。我想实现类似的功能,但要使用RecyclerView。

android android-recyclerview android-architecture-components android-viewmodel
1个回答
0
投票

ViewModel不能用于RecyclerView项目

为什么?

[ViewModel是AAC ((Android体系结构组件)],其唯一目的是在Android Activity / Fragment生命周期的配置更改中幸存下来,以便在这种情况下可以通过ViewModel保留数据。

这就是为什么不应该在RecyclerView ((ViewHolder)项目上使用它,因为Item View本身将是Activity / Fragment的一部分,并且它(RecyclerView / ViewHolder)不包含任何特定的API提供ViewModelStoreOwner (从中基本派生给定Activity / Fragment实例的ViewModels

获得ViewModel的简单语法是:

ViewModelProvider(this).get(ViewModel::class.java)

&这里this将被称为活动/片段上下文。

因此,即使您最终在ViewModel项目中使用了RecyclerView,由于上下文可能是Activity / Fragment在RecyclerView中是相同的,这也会给您带来相同的实例,这对我来说没有意义。因此,ViewModel对于RecyclerView无效,或者对这种情况没有太大帮助。


TL; DR

解决方案?

您可以直接从LiveData类中的活动/片段的ViewModel中传递需要观察的RecyclerView.Adapter对象。您还需要为适配器提供LifecycleOwner,以开始观察给定的实时数据。

所以您的Adapter类如下所示:

class RecyclerViewAdapter(private val liveDataToObserve: LiveData<T>, private val lifecycleOwner: LifecycleOwner) : RecyclerView.Adapter<ViewHolder>() {

    init {
        liveDataToObserve.observe(lifecycleOwner) { t ->
            // Notify data set or something...
        }
    }

}

如果不是这种情况,并且您想在ViewHolder类中使用它,则可以在LiveData方法期间将onCreateViewHolder对象与lifecycleOwner一起传递给ViewHolder实例。

奖励点!

如果在RecyclerView项上使用数据绑定,则可以轻松地从绑定类中获取lifecyclerOwner对象。您所需要做的就是在onCreateViewHolder()期间进行设置,如下所示:

class RecyclerViewAdapter(private val liveDataToObserve: LiveData<T>, private val lifecycleOwner: LifecycleOwner) : RecyclerView.Adapter<ViewHolder>() {

    override fun onCreateViewHolder: ViewHolder {
        // Some piece of code for binding
        binding.lifecycleOwner = [email protected]
        // Another piece of code and return viewholder
    }

}

class ViewHolder(private val someLiveData: LiveData<T>, binding: ViewDataBinding): RecyclerView.ViewHolder(binding.root) {

    init {
        someLiveData.observe(requireNotNull(binding.lifecycleOwner)) { t->
            // set your UI by live data changes here
        }
    }
}

所以是的,您可以为ViewHolder实例使用包装器类来为您提供LiveData,但如果包装器类扩展了ViewModel类,我不建议这样做。

[一旦考虑模仿onCleared()ViewModel方法,您可以在包装类上创建一个方法,该方法在ViewHolder回收或通过方法onViewRecycled()onViewRecycled()从窗口分离时被调用)最适合您的情况。

© www.soinside.com 2019 - 2024. All rights reserved.