MergeAdapter是recyclerview中引入的新类:1.2.0-alpha02,使您可以将多个显示适配器组合到一个RecyclerView中。这将允许您封装适配器中每个单元的逻辑,并允许将来重用它。
问题
让我们从一个例子开始。假设我们有一个任务来显示具有两种数据类型的提要-带有描述的文本和图片。
onCreateViewHolder
在最常见的情况下,该方法中的代码如下所示:
override fun onCreateViewHolder(
parent: ViewGroup, viewType: Int
): RecyclerView.ViewHolder? {
val holder: RecyclerView.ViewHolder
val inflater = LayoutInflater.from(parent.context)
when (viewType) {
TEXT_VIEW_TYPE -> {
holder = TextViewHolder(
inflater.inflate(R.layout.text_item, parent, false)
)
}
IMAGE_VIEW_TYPE -> {
holder = ImageViewHolder(
inflater.inflate(R.layout.image_item, parent, false),
imageClickListener
)
}
else -> {
throw IllegalArgumentException(
"Can't create view holder from view type $viewType"
)
}
}
return holder
}
为什么这么糟?此实现的缺点是违反了DRY和SOLID的原则(单一责任和开放封闭)。为了确保这一点,添加两个要求就足够了:输入一种新的数据类型(复选框)和另外一个磁带,其中仅包含复选框和图片。
我们面临一个选择-为第二个磁带使用相同的适配器还是创建一个新的适配器?无论我们选择哪种解决方案,我们都必须更改代码(大约是同一件事,但是在不同的地方)。必须添加新的VIEW_TYPE,ViewHolder和编辑方法:
getItemViewType(), onCreateViewHolder() onBindViewHolder()
。
如果我们决定保留一个适配器,那么更改将在那里结束。但是,如果将来将具有新逻辑的新数据类型仅添加到第二个提要中,则第一个提要将具有额外的功能,并且尽管未更改,但也需要进行测试。
如果我们决定创建一个新的适配器,将会有很多重复的代码。
决断
新的MergeAdapter类允许您为不同类型的单元格组合不同的适配器。例如,一个非常常见的用例是在Feed中加载数据时显示微调框,如果突然发生加载错误,则在Feed末尾显示有错误的单元格。
可以使用MergeAdapter来解决此问题,假设我们有3个适配器:
val firstAdapter: FirstAdapter = …
val secondAdapter: SecondAdapter = …
val thirdAdapter: ThirdAdapter = …val mergeAdapter = MergeAdapter(firstAdapter, secondAdapter, thirdAdapter)
recyclerView.adapter = mergeAdapter
RecyclerView将按传递给构造函数的顺序依次显示每个适配器的项。不同的适配器使您可以为列表中的不同单元格分隔逻辑。例如,如果您需要在列表中添加标题,则不需要在适配器中实现此逻辑(该逻辑负责显示列表中的主要内容),则可以将适配器用于不同类型的单元格。这种方法有助于封装逻辑并在将来用于不同的屏幕。
在标题的顶部或列表的底部显示下载内容。
要在列表的顶部或底部显示下载状态,您需要分别添加适配器:
val mergeAdapter = MergeAdapter(headerAdapter, listAdapter, footerAdapter)
recyclerView.adapter = mergeAdapter
顶部的单元格和底部的单元格使用相同的布局,ViewHolder和UI逻辑(显示加载状态和隐藏)。通常,对于列表的顶部和底部,使用同一适配器的2个实例就足够了。可以在此处或此处找到示例。
简而言之,如果您将复杂的适配器与不同类型的单元格一起使用,则可以通过这种简单的方法来改进项目的代码。
你喜欢这篇文章吗?不要忘记在Telegram和AndroidSchool.ru平台上加入我们,为Android开发人员提供有用的材料和现代教程。