ConcatAdapter 简介
ConcatAdapter 让我们可以顺序显示多个 Adapter 中的内容。例如,假设我们有下面三个 Adapter:
val firstAdapter: FirstAdapter = …
val secondAdapter: SecondAdapter = …
val thirdAdapter: ThirdAdapter = …
val concatAdapter= ConcatAdapter(firstAdapter, secondAdapter,
thirdAdapter)
concatAdapter =
RecyclerView 将会按 Adapter 顺序显示所有的项目。
△ RecyclerView 和 Adapter 数据
在头部和底部显示加载状态
val concatAdapter = ConcatAdapter(headerAdapter, listAdapter,
footerAdapter)
recyclerView.adapter = concatAdapter
要获得完整的实现,请查看这里拉取请求,它添加了:
从 ViewModel 中暴露出来的 LoadState
显示加载状态的头部和底部的布局
头部和底部的 ViewHolder 对象
一个 ListAdapter,它基于 LoadState 显示 1 或 0 个项目,每次 LoadState 有变动的时候,我们会通知相应条目进行改动、插入或移除 (您可以在拉取请求中查看相应的代码)。
🔎 更多关于 ConcatAdapter 的信息
ViewHolder
⚠️ 如果要支持不同的 ViewHolder 类型,您应该实现 Adapter.getItemViewType 方法。当您复用 ViewHolder 时,确保同一视图类型没有对应不同的 ViewHodler!防止出现这个问题的最佳实践之一,便是将布局 ID 作为视图类型返回。
<!-- Copyright 2019 Google LLC.
SPDX-License-Identifier: Apache-2.0 -->
class HeaderAdapter() : RecyclerView.Adapter<LoadingStateViewHolderHeaderViewHolder>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
return LoadingStateViewHolder(parent)
}
override fun getItemViewType(position: Int): Int {
- return 0
+ return R.layout.list_loading
}
}
class FooterAdapter() : RecyclerView.Adapter<LoadingStateViewHolderFooterViewHolder>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
return LoadingStateViewHolder(parent)
}
override fun getItemViewType(position: Int): Int {
- return 0
+ return R.layout.list_loading
}
}
getItemViewType
https://developer.android.google.cn/reference/androidx/recyclerview/widget/RecyclerView.Adapter#getItemViewType(int)
相比于使用 stable id 搭配 notifyDataSetChanged,我们更建议使用 Adapter 的特定通知事件,该事件可以为RecyclerView 提供更多有关数据集更改的信息,从而使 RecyclerView 可以更有效率地更新 UI,同时也有更好的动画效果。如果您正在使用 ListAdapter 的话,其内部会使用 DiffUtil 回调帮您处理通知事件。但是如果您需要使用 stable id,ConcatAdapter.Config 为其提供了三种不同的配置:NO_STABLE_IDS、ISOLATED_STABLE_IDS 和 SHARED_STABLE_IDS。其中后面两种需要您自己处理 Adapter 中的 stable id。您可以查看 StableIdMode 文档来获得更多关于其工作原理的信息。
notifyDataSetChanged
https://developer.android.google.cn/reference/androidx/recyclerview/widget/RecyclerView.Adapter
ListAdapter
https://developer.android.google.cn/reference/kotlin/android/widget/ListAdapter
DiffUtil
https://developer.android.google.cn/reference/androidx/recyclerview/widget/DiffUtil
NO_STABLE_IDS、ISOLATED_STABLE_IDS、SHARED_STABLE_IDS、StableIdMode
https://developer.android.google.cn/reference/androidx/recyclerview/widget/ConcatAdapter.Config.StableIdMode
notifyItemRangeChanged、notifyDataSetChanged
https://developer.android.google.cn/reference/androidx/recyclerview/widget/RecyclerView.Adapter
ListAdapter
https://developer.android.google.cn/reference/kotlin/androidx/recyclerview/widget/ListAdapter
SortedList
https://developer.android.google.cn/reference/androidx/recyclerview/widget/SortedList
查找 ViewHolder 位置
以上就是全部了!总结一下: 如果要顺序显示不同类型的数据的同时,也希望这些数据能够封装在它们自己的 Adapter 中,请开始使用 ConcatAdapter;如果想要更进一步对 ViewHolder 池和 statle id 进行高级控制,则要使用 ConcatAdapter.Config。
推荐阅读