gpt4 book ai didi

android - 查看 Recycler 的模型查看项目

转载 作者:行者123 更新时间:2023-12-04 11:13:23 26 4
gpt4 key购买 nike

我的 Activity 有一个谷歌的 ViewModel 来获取一些模型项目。然后将这些项目转换为 RecyclerView 的适配器项目。一个 RecyclerView 还支持多种类型的适配器项。

我想为这些模型对象中的每一个拥有单独的 View 模型对象,以便我可以将更复杂的逻辑封装在那个“小” View 模型中。

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

我正在考虑使用 ViewModelProvider::get(key, modelClass)但是我的元素会随着时间的推移而变化,我找不到“清除”旧元素的好方法。

您如何在项目中处理这些案例?

编辑:要添加有关我的关注的更多信息,也许用不同的词:我希望我的“小” View 模型与它所代表的模型项一样长。代表着:

  • 我必须在这些项目的父项接收
  • 的相同场景中接收 onCleared() 回调
  • 当项目不再是
  • 时,我必须接收 onCleared() 回调

    编辑:请尝试将其与以 fragment 作为项目的 ViewPager 进行比较。每个单独的模型项都表示为带有其 ViewModel 的 fragment 。我想实现类似的东西,但对于 RecyclerView。

    最佳答案

    androidx.lifecycle.ViewModel默认情况下,不打算在 RecyclerView 项目上使用
    为什么?
    ViewModel is AAC (Android 架构组件),其唯一目的是在 Android 的配置更改中幸存下来 Activity/fragment 生命周期,以便在这种情况下可以通过 ViewModel 持久化数据。
    这是通过在与托管 Activity 相关的存储中缓存 VM 实例来实现的。
    这就是为什么它不应该直接用于 RecyclerView (ViewHolder) 项目,因为项目 View 本身将是 Activity/Fragment 的一部分,并且它 (RecyclerView/ViewHolder) 不包含任何特定的 API 来提供 ViewModelStoreOwner (对于给定的 Activity/Fragment 实例,ViewModel 基本上是从中派生的)。
    获取 ViewModel 的简单语法是:

    ViewModelProvider(this).get(ViewModel::class.java)
    在这里 this 将被称为 Activity/fragment 上下文。
    所以即使你最终使用 ViewModelRecyclerView项目,它会给你相同的实例,因为上下文可能是 Activity/Fragment 在 RecyclerView 中是相同的,这对我来说没有意义。所以 ViewModel 对 RecyclerView 没用,或者它对这种情况没有多大贡献。

    TL;博士
    解决方案?
    可以直接传入 LiveData您需要从 Activity/Fragment 的 ViewModel 中观察到的对象在您的 RecyclerView.Adapter类(class)。您需要提供 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 期间的对象方法到您的 ViewHolder 实例以及 lifecycleOwner .
    加分!
    如果您在 RecyclerView 项目上使用数据绑定(bind),那么您可以轻松获得 lifecyclerOwner绑定(bind)类中的对象。您需要做的就是在 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 = this@RecyclerViewAdapter.lifecycleOwner
    // 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,我会不鼓励这样做类(class)。
    只要关注模仿 onCleared() ViewModel的方法,您可以在包装类上创建一个方法,该方法在 ViewHolder 时被调用通过方法 onViewRecycled() 被回收或从窗口分离或 onViewDetachedFromWindow() 最适合您的情况。

    编辑 @Mariusz 的评论:关注使用 Activity/fragment 作为 生命周期所有者 是正确的。但将其解读为 POC 可能会产生轻微的误解。
    只要有人使用 lifecycleOwner观察 LiveData在给定的 RecyclerViewHolder项目,这样做是可以的,因为 LiveData是生命周期感知组件,它在内部处理对生命周期的订阅,因此可以安全使用。即使您可以根据需要显式删除观察,使用 onViewRecycled()onViewDetachedFromWindow()方法。
    关于 ViewHolder里面的异步操作:
  • 如果你使用协程,那么你可以使用 lifecycleScope来自 lifecycleOwner调用您的操作,然后将数据提供回特定观察 LiveData没有明确处理明确的情况( LifecycleScope 会为你处理它)。
  • 如果不使用协程,那么您仍然可以进行 asyc 调用并将数据提供给观察 LiveData而且不用担心在 onViewRecycled() 期间清除您的异步操作或 onViewDetachedFromWindow()回调。这里重要的是LiveData尊重给定 LifecycleOwner 的生命周期,而不是正在进行的异步操作。
  • 关于android - 查看 Recycler 的模型查看项目,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61364874/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com