此次想要介绍的是由谷歌推出的MergeAdapter
。听名字就应该知道它是和RecyclerView
相关的组件。android
该组件是在androidx.recyclerview:recyclerview:1.2.0-alpha02
中推出,它的主要中做用是把多个Adapter
集中在一个Adapter
中,而后在RecyclerView
中显示。git
正常的Adapter
是只能存在一种ViewType
,因此若是想实现RecyclerView
中显示不一样的ViewType
则须要本身额外进行扩展,或者使用相似于Groupie
(关于Groupie的教程)的外部库。github
可是有了MergeAdapter
, 咱们能够直接使用它就能够实现上述的需求,很是的方便。数组
废话很少说,先介绍用法,而后再讨论它的好与不足。app
在build.gradle
中加入RecyclerView
的库。ide
androidx.recyclerview:recyclerview:1.2.0-alpha02
复制代码
这里根据本身的需求建立layout,须要多少ViewType
就建立相应的layout就能够了。post
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="50dp">
<TextView
android:id="@+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@android:color/black"
android:textSize="20sp"
android:layout_marginStart="20dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
tools:text="hello" />
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
复制代码
这里也是根据本身的需求建立Adapter就能够了。和正常的用法同样。gradle
class FirstAdapter(private val data: List<String>) :
ListAdapter<String, FirstAdapter.ViewHolder>(DiffCallback()) {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val inflater = LayoutInflater.from((parent.context))
val binding: ItemFirstBinding =
DataBindingUtil.inflate(inflater, R.layout.item_first, parent, false)
return ViewHolder(binding)
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
holder.binding.textView1.text = data[position]
}
override fun getItemCount(): Int {
return data.size
}
class DiffCallback : DiffUtil.ItemCallback<String>() {
override fun areContentsTheSame(oldItem: String, newItem: String): Boolean {
return oldItem == newItem
}
override fun areItemsTheSame(oldItem: String, newItem: String): Boolean {
return oldItem === newItem
}
}
class ViewHolder(var binding: ItemFirstBinding) : RecyclerView.ViewHolder(binding.root)
复制代码
咱们在MainActivity中建立MergeAdapter
而后传RecyclerView
。ui
val firstAdapter = FirstAdapter(data)
val secondAdapter = SecondAdapter(data)
val thirdAdapter = ThirdAdapter(data)
// 建立MergeAdapter
// 须要经过listOf把多个adapter传给MergeAdapter
mergeAdapter = MergeAdapter(listOf(firstAdapter,secondAdapter,thirdAdapter))
binding.recyclerView.adapter = mergeAdapter
复制代码
能够对已经存在的adapter进行移除。spa
mergeAdapter.removeAdapter(firstAdapter)
复制代码
能够在MergeAdapter
传给RecyclerView
之后,还以能够添加adapter。
mergeAdapter.addAdapter(firstAdapter)
复制代码
能够获取当前已经传给RecyclerView
的adapter数组。
val adapters = mergeAdapter.adapters
复制代码
默认的状况是每一个adapter
都会维护本身的ViewHolder pool
,且adapter
之间不能复用。若是咱们想要复用则须要设置MergeAdapter.Config
。
val configBuilder = MergeAdapter.Config.Builder()
configBuilder.setIsolateViewTypes(false)
复制代码
而后在建立MergeAdapter
的时候,把Config
传进去。
val mergeAdapter = MergeAdapter(configBuilder.build(),listOf(firstAdapter,secondAdapter,thirdAdapter))
复制代码
须要有新数据更新时调用相应的adapter
, 而后用相应的adapter
的notifyDatasetChanged
。调用adapter
的notifyDatasetChanged
,最后MergeAdapter
的notifyDatasetChanged
也会被调用。
thirdAdapter.submitList(addData())
thirdAdapter.notifyDataSetChanged()
复制代码
有点天然没必要多说,可是MergeAdapter
有一个显而易见的不足之处就是ViewType
不能混合使用,使其应用范围受到了很大的限制。可是若是没有这样的需求则仍是优先使用MergeAdapter
吧!
GitHub: github.com/HyejeanMOON…
关于Jetpack的Paging教程: juejin.im/post/5e75db…
Groupie的教程: juejin.im/post/5e9059…