gpt4 book ai didi

android - 用特定于UI的数据增强PagedList且不破坏MVVM模式的最佳方法

转载 作者:行者123 更新时间:2023-12-03 10:31:05 26 4
gpt4 key购买 nike

我是MVVM模式的新手,但我真的很喜欢PagedList如何简化存储库中分页数据的使用。
但是现在我有以下情况:

  • 我的存储库具有如下方法:fun getLibraryItems(): LiveData<PagedList<ItemInfo>>

  • 其中 ItemInfo是存储库特定的,并且不“了解” UI。
  • 接下来,我想使用UI特定数据(映射到另一个ui数据对象)来“增强”该数据对象,我只能从上下文感知的组件(例如这是Drawable资源。

  • 但是,如果需要的话,我无法直接从 PagedList<X>映射到另一个 PagedList<Y>-我需要更新数据源以接受“映射器”功能,如下所示:
    fun <T> getLibraryItems(mapper: (ItemInfo) -> T): LiveData<PagedList<T>> {
    return dataSource
    .getLibraryItems()
    .map(mapper)
    .toLiveData()
    }
    这样,我可以将 ItemInfo映射到特定于UI的UI类型 T,但是我无法在ViewModel中做到这一点,因为(据我所知)在ViewModel中加载Drawable资源是反模式。
    我不知道如何以及在何处将其称为“映射器”,应该是“ Activity ”/“片段”,还是我错过了smth和过于复杂的事物。

    最佳答案

    我认为有可能按照您的建议在ViewModel内映射数据,但与其在此处加载Drawable资源,不如仅传递其标识符。然后在您的UI层(RecyclerView Adapter,Activity或其他)中,通过其标识符加载资源。这样,您就不必在ViewModel中处理特定于上下文的方法。另外,如果您不想处理android资源ID(例如R.drawable.my_image),则必须保留自己的ID系统,然后将其映射到UI层内的android资源ID,尽管我个人认为这是多余的并发症。

    编辑:重新阅读您的问题后,我发现我的帖子没有完全回答它,所以这里有更多关于体系结构的内容:
    由于您要将域对象映射到特定于UI的对象,因此在ViewModel中这样做不是最佳实践,而不是clean architecture方式,这是正确的。因此正确的方法是在显示对象之前在UI层中进行此类映射。由于您使用PagedList,因此我可以假设您的RecyclerView适配器扩展了PagedListAdapter。然后,您可以创建抽象以支持适配器内部的映射。

    abstract class MyPagedAdapter<T, R, VH: RecyclerView.ViewHolder>(
    val dataMapper: (T)->R,
    diffCallback: DiffUtil.ItemCallback<T>
    ): PagedListAdapter<T, VH>(diffCallback) {
    fun getMappedItem(position: Int) = dataMapper.invoke(getItem(position))
    }


    class LibraryItemAdapter(
    dataMapper: (LibraryItem)->UILibraryItem,
    ): MyPagedAdapter<LibraryItem, UILibraryItem, ViewHolderType>(dataMapper, /* provide diff callback here */) {
    /* implement onCreateViewHolder and getItemViewType here */

    override fun onBindViewHolder(holder: ViewHolderType, position: Int) {
    val item = getMappedItem(position)
    // configure view holder to display selected item
    }

    }


    // Then inside your fragment/activity:
    val mapper: (LibraryItem) -> UILibraryItem = { /* use your context-aware components to create an object for UI */ }
    recyclerView.adapter = LibraryItemAdapter(mapper)
    PS:我还想强调一点,将您的ViewModel/Repository/elsewhere中的整个列表映射到另一个包含Drawable,Bitmap或任何其他大型结构的类是一个坏主意,您最终可能会用Drawables淹没内存现在甚至不会显示。仅在要使用可绘制对象且不将其存储在列表中时才获取它们。我最初的答案和后来的修改都使您无法这样做
    P.P.S .:不要在您的映射器中进行过多的工作,因为当用户快速滚动大列表时,它可能会大量加载UI线程。在域/存储库层中执行所有业务逻辑。

    关于android - 用特定于UI的数据增强PagedList且不破坏MVVM模式的最佳方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65740094/

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