MergeAdapter是一个提供的新类recyclerview:1.2.0-alpha02,通过该类您可以顺序合并多个adapters以单个显示RecyclerView。这使您可以更好地封装适配器,而不必将许多数据源组合到单个适配器中,从而使它们集中并可重复使用。

一个用例是在页眉或页脚中显示列表加载状态:当列表从网络中检索数据时,我们想显示一个进度条。如果出现错误,我们要显示错误和重试按钮。

一个带有页脚的RecyclerView,显示加载状态:进度或错误

简介 MergeAdapter

MergeAdapter允许我们按顺序显示多个适配器的内容。例如,假设我们有以下3个适配器:

val firstAdapter:FirstAdapter =… 
val secondAdapter:SecondAdapter =…
val thirdAdapter:ThirdAdapter =… val mergeAdapter = MergeAdapter(firstAdapter,secondAdapter,
thirdAdapter)recyclerView.adapter = mergeAdapter

recyclerView将显示来自每个适配器顺序的项目。

使用不同的适配器可以使您更好地区分列表的每个顺序部分。例如,如果要显示标题,则无需将与标题显示相关的逻辑放在处理列表显示的同一适配器中,而是可以将其封装在其自己的适配器中。

在页眉和页脚中显示加载状态

我们的页眉/页脚显示进度指示器或报告错误。列表成功完成加载后,页眉/页脚不应显示任何内容。因此,可以使用自己的适配器将其表示为包含0或1个项目的列表:

val mergeAdapter = MergeAdapter(headerAdapter,listAdapter,
footerAdapter)recyclerView.adapter = mergeAdapter

如果页眉和页脚使用相同的布局ViewHolder和UI逻辑(例如,显示进度以及显示方式),则可以仅实现一个Adapter类并创建2个实例:一个用于页眉,一个用于页脚。

要实现完整的实现,请查看此pull request,其中添加了:

  • LoadState,从ViewModel
  • 加载状态页眉和页脚布局
  • ViewHolder的页眉和页脚对象
  • ListAdapter那显示0或1项基于所述LoadState。每次LoadState更改时,我们都会通知您需要更改,插入或删除项目(请参见代码)。

about有关MergeAdapter的更多信息

ViewHolders

默认情况下,每个适配器都维护自己的ViewHolders 池,并且在适配器之间不重复使用。如果多个适配器显示相同ViewHolder,我们可能要在它们之间重用实例。我们可以通过构造MergeAdapter一个MergeAdapter.Config对象where 来实现这一点isolateViewTypes = false。这样,所有合并的适配器将使用相同的视图池。在加载状态页眉和页脚示例中,两者ViewHolders实际上将显示相同的内容,因此我们可以重复使用它们。

To️为了支持不同的ViewHolder类型,您应该实现。重用时,请确保相同的视图类型没有指向不同的视图!一种最佳实践是将布局ID作为视图类型返回。Adapter.getItemViewTypeViewHoldersViewHolders

使用稳定的ID

建议不要使用稳定的id与一起使用notifyDataSetChanged,建议使用适配器的特定通知事件,该事件提供RecyclerView有关数据集更改的更多信息。这样可以RecyclerView更有效地更新UI并使用更好的动画。如果您正在使用,ListAdapter则在DiffUtil回调的帮助下,将在后台为您处理notify事件。但是,如果你需要使用稳定的ID,将MergeAdapter.Config提供3种不同的配置,稳定的IDS: NO_STABLE_IDSISOLATED_STABLE_IDSSHARED_STABLE_IDS。最后两个要求您处理适配器中的稳定ID。查看StableIdMode文档以获取有关其工作方式的更多信息。

数据变更通知

当适配器的适配器部分MergeAdapter调用通知功能之一时,MergeAdapter在更新之前,计算新项目的位置RecyclerView

RecyclerView的角度来看,notifyItemRangeChanged意味着项目是相同的,只是其内容发生了变化。notifyDataSetChanged表示前后之间没有关系。因此,我们无法映射notifyDataSetChangednotifyItemRangeChanged

如果适配器调用Adapter.notifyDataSetChangedMergeAdapter也会调用Adapter.notifyDataSetChanged,而不是Adapter.notifyItemRangeChanged。与RecyclerViews避免调用一样,请像往常一样使用Adapter.notifyDataSetChanged()更细致的更新或使用可Adapter自动执行此更新的实现,例如ListAdapterSortedList

查找ViewHolder位置

ViewHolder.getAdapterPosition过去可能曾经使用过a ViewHolder在适配器中的位置。现在,因为我们要合并多个适配器,所以请使用ViewHolder.getBindingAdapterPosition()。如果要获取最后绑定a的适配器,ViewHolder请在共享的情况下ViewHolders使用ViewHolder.getBindingAdapter()


就这样!如果要顺序显示不同类型的数据,这些数据将从封装在自己的适配器中受益,请开始使用MergeAdapter。要对ViewHolder池和稳定ID 进行高级控制,请使用MergeAdapter.Config

分类: 未分类

bayshier

愿世间每个美好的灵魂都能被温柔以待

发表评论

电子邮件地址不会被公开。 必填项已用*标注