本文是关于RecyclerView的介绍性文章系列的第二篇。如果您已经对创建RecyclerView有所了解,请继续阅读本文。如果你不熟悉,建议你先看这个系列的第一篇文章。
RecyclerView可以非常高效地显示列表数据。对于静态列表数据,默认适配器就足够了。然而,在大多数情况下,RecyclerView的数据是动态的。以备忘工作的应用为例。的主要操作是添加新的工作项和删除已完成的工作项。NotifyItemInserted()可以向指定位置添加新任务,但是当需要删除元素时问题就来了。notifyItemRemoved()仅在您知道要删除的任务的位置时才起作用。虽然可以编写代码来确定要删除的任务的位置,然后调用notifyItemRemoved(),但是代码会变得非常复杂。调用notifyDataSetChanged()也是一个选项,但是它会重绘整个视图,包括数据未改变的部分,这使得操作开销更大。ListAdapter可以在不重绘视图的情况下处理元素的添加和删除,甚至可以为更改添加动画效果。
使用ListAdapter的另一个好处是,在添加或删除元素时还可以添加动画。这样,用户可以直观地看到列表数据的变化。虽然不用ListAdapter也能实现动画效果,但是需要开发者自己实现,同样的性能是无法实现的,因为带动画的视图需要重画。
添加元素的动画效果。
添加元素的动画效果。
处理差异比较
DiffUtil是ListAdapter能够高效改变元素的秘诀。DiffUtil比较新旧列表中添加、移动或删除了哪些元素,然后输出更新操作列表,以高效地将原始列表中的元素转换为新元素。
为了能够识别新数据,DiffUtil要求您重写areItemsTheSame()和areContentsTheSame()。AreItemsTheSame()检查两个元素是否相同。AreContentsTheSame()检查两个元素是否包含相同的数据。
areitemname()的比较元素示意图
arecontthesame()比较元件示意图
在适配器类中添加DiffUtil对象,并重写areItemsTheSame()和areContentsTheSame()。
!-版权所有2019GoogleLLC。
SPDX-许可证标识符:Apache-2.0 -
objectFlowerDiffCa
llback : DiffUtil.ItemCallback<Flower>() { override fun areItemsTheSame(oldItem: Flower, newItem: Flower): Boolean { return oldItem.id == newItem.id } override fun areContentsTheSame(oldItem: Flower, newItem: Flower): Boolean { return oldItem == newItem }}将 Adapter 的父类由 RecyclerView.Adapter 改为 ListAdapter,并传入 DiffCallback。
<!-- Copyright 2019 Google LLC. SPDX-License-Identifier: Apache-2.0 --> class FlowerAdapter : ListAdapter<String, FlowerAdapter.FlowerViewHolder>(FlowerDiffCallback)
更新列表
ListAdapter 通过 submitList() 方法获取数据,该方法提交了一个列表来与当前列表进行对比并显示。也就是说您无需再重写 getItemCount(),因为 ListAdapter 会负责管理列表。
在 Activity 类中,调用 Adapter 的 submitList() 方法并传入数据列表。
<!-- Copyright 2019 Google LLC. SPDX-License-Identifier: Apache-2.0 -->val flowerList = resources.getStringArray(R.array.flower_array).toMutableList()val flowerAdapter = FlowerAdapter()flowerAdapter.submitList(flowerList)
在 Adapter 类中,onBindViewHolder() 现在可以使用 getItem() 从数据列表中获取指定位置的元素了。
<!-- Copyright 2019 Google LLC. SPDX-License-Identifier: Apache-2.0 -->override fun onBindViewHolder(holder: FlowerViewHolder, position: Int) { holder.bind(getItem(position))}
就这么简单。仅需几步简单操作就可以在您的 RecyclerView 中使用 ListAdapter。现在您的应用可以通过使用 ListAdapter 来更新那些发生变化的元素以获得更好的性能和用户体验了。
下一步
关于 ListAdapter 的 完整示例代码 都在这里。
感谢阅读 RecyclerView 系列 的第二篇文章。请继续关注未来更多关于 RecyclerView 的内容。
如果您想了解更多关于 ListAdapter 的内容,请参考 官方文档。
评论(0)