一、概念
顾名思义不用操心 view 的复用,通过 LayoutManager 可设置数据的不同展示方式例如列表网格瀑布流,还可以设置条目添加删除的动画和间隔样式。
二、使用
2.1 基本使用
当复杂条目显示的时候,例如 position=1 的时候显示轮播图,那么 getItemCount() 返回 list.size() 要 +1,onBindViewHolder() 的时候拿数据 list.get(positon-1) 要减掉,分页加载在尾部添加一个 item 的话,getItemCount() 要再 +1。
class DemoAdapter(
val context: Context
) : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
private val typeOne = 1
private val typeTwo = 2
private var dataList = mutableListOf<String>() //数据不通过构造传入而是提供setter因为后期需要更新
//创建viewholer的时候调用
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
//根据不同类型的Item返回不同的ViewHolder
return if (viewType == typeOne) {
DemoViewHolder.OneViewHolder(LayoutInflater.from(context).inflate(R.layout.item_one, parent, false))
} else {
DemoViewHolder.TwoViewHolder(LayoutInflater.from(context).inflate(R.layout.item_two, parent, false))
}
}
//绑定viewholder的时候调用
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
//对不同类型的Item设置数据
when (holder) {
is DemoViewHolder.OneViewHolder -> {
holder.tvName.text = dataList[position]
}
is DemoViewHolder.TwoViewHolder -> {
holder.tvName.text = dataList[position]
}
}
}
//Item的总数
override fun getItemCount(): Int {
return dataList.size
}
//Item类型区分逻辑
override fun getItemViewType(position: Int): Int {
return if (position % 2 == 0) typeTwo else typeOne
}
//每一种布局都要写一个ViewHolder
private sealed interface DemoViewHolder {
class OneViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView), DemoViewHolder {
val tvName: TextView = itemView.findViewById(R.id.tvName)
}
class TwoViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView), DemoViewHolder {
val tvName: TextView = itemView.findViewById(R.id.tvName)
}
}
//上拉加载(往集合尾部追加)
fun loadMore(list: List<String>) {
dataList.addAll(list)
}
//下拉刷新(集合重新赋值)
fun refresh(list: List<String>) {
dataList = list.toMutableList()
}
}
class DemoActivity : AppCompatActivity() {
private lateinit var adapter: DemoAdapter
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val recyclerView = findViewById<RecyclerView>(R.id.recyclerView)
recyclerView.layoutManager = LinearLayoutManager(this)
val adapter = DemoAdapter(this)
recyclerView.adapter = adapter
}
}
2.2 点击回到顶部
recyclerView.scrollToPosition(0)
2.3 平滑的滚到某个位置
recycleView.smoothScrollToPosition(5)
2.4 去掉边界水波纹
android:overScrollMode="never"
2.5 解决嵌套滑动卡顿
RecyclerView 嵌套 RecyclerView 的情况下会引起滑动冲突,默认情况下外层的RecyclerView可滑,内层不可滑。
Nestedscrollview 是官方为了解决滑动冲突问题而设计的新的View,可以优化成 NestScrollView 嵌套 RecyclerView 方案。nestedScrollingEnabled 含义是支持嵌套滚动,默认情况下 RecyclerView 会随着 NestScrollView 滚动而滚动,放弃了自己的滚动,从而感觉到滞留卡顿。设为 false 来让 RecyclerView 能正常滚动。
android:nestedScrollingEnabled="false"
2.6 添加分割线
//系统自带分割线
recyclerView.addItemDecoration(DividerItemDecoration(this,DividerItemDecoration.VERTICAL))
//自定义分割线
val divider = DividerItemDecoration(this,DividerItemDecoration.VERTICAL)
val dividerDrawable = AppCompatResources.getDrawable(this, R.drawable.custom_divider)
dividerDrawable?.let {
divider.setDrawable(it)
}
recyclerView.addItemDecoration(divider)
三、ConcatAdaper
假设 RecyclerView 内容被分为 Header、Content、Footer 三部分且它们的布局均不相同,通常是使用不同的 ViewType 来实现,现在是分别写三个Adapter,再通过 ConcatAdapter 顺序地组合多个 Adapter 并让它们显示在同一个 RecyclerView 中。
3.1 写三个xml布局:Header、Content、Footer
3.2 写三个继承自RecyclerViewer.Adapter的适配器

本文详细介绍了RecyclerView的使用,包括设置LayoutManager、处理ViewType、点击事件、滚动操作以及去除边界水波纹。重点讲解了DiffUtil的使用,以提高数据更新的效率和性能,并介绍了ViewHolder的缓存机制,包括不同级别的缓存和存取流程。此外,还提到了ConcatAdapter用于合并多个Adapter以及如何自定义缓存策略。最后讨论了RecyclerView的性能优化技巧,如设置固定大小、预取项和控制滑动速度等。
最低0.47元/天 解锁文章
3351

被折叠的 条评论
为什么被折叠?



