Android中RecyclerView基本使用
一、RecyclerView 核心概念
1. 基本组件关系
2. 核心组件作用
Adapter:数据与视图的桥梁
LayoutManager:控制布局方式(线性/网格/瀑布流)
ViewHolder:缓存视图组件
ItemDecoration:添加分割线等装饰
ItemAnimator:处理增删动画
二、基础使用流程
1. 添加依赖
implementation 'androidx.recyclerview:recyclerview:1.3.2'
2. XML布局
<androidx.recyclerview.widget.RecyclerViewandroid:id="@+id/recyclerView"android:layout_width="match_parent"android:layout_height="match_parent"/>
3. 实现 Adapter
class MyAdapter(private val data: List<String>) : RecyclerView.Adapter<MyAdapter.MyViewHolder>() {// 创建 ViewHolderoverride fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder {val view = LayoutInflater.from(parent.context).inflate(R.layout.item_layout, parent, false)return MyViewHolder(view)}// 绑定数据override fun onBindViewHolder(holder: MyViewHolder, position: Int) {holder.bind(data[position])}override fun getItemCount() = data.size// ViewHolder 定义inner class MyViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {private val textView: TextView = itemView.findViewById(R.id.tv_item)fun bind(item: String) {textView.text = item}}
}
4. 设置 RecyclerView
val recyclerView = findViewById<RecyclerView>(R.id.recyclerView)
recyclerView.layoutManager = LinearLayoutManager(this)
recyclerView.adapter = MyAdapter(listOf("Item 1", "Item 2", "Item 3"))
三、ViewHolder 生命周期详解
关键生命周期方法:
onCreateViewHolder()
:创建新视图onBindViewHolder()
:绑定数据onViewAttachedToWindow()
:视图进入屏幕onViewDetachedFromWindow()
:视图离开屏幕onViewRecycled()
:视图进入回收池(可在此释放资源)
四、性能优化策略
1. 基础优化
// 设置固定尺寸提升测量效率
recyclerView.setHasFixedSize(true) // 增加缓存数量(默认=2)
recyclerView.itemViewCacheSize = 10
2. 高效数据绑定
override fun onBindViewHolder(holder: MyViewHolder, position: Int) {// 使用 payload 实现局部更新holder.bind(data[position])
}// 使用 DiffUtil 智能更新
val diffResult = DiffUtil.calculateDiff(MyDiffCallback(oldList, newList))
diffResult.dispatchUpdatesTo(adapter)
3. 视图复用优化
// Adapter 中重写 getItemViewType()
override fun getItemViewType(position: Int): Int {return when (data[position].type) {ItemType.TEXT -> 0ItemType.IMAGE -> 1}
}// 根据 viewType 创建不同 ViewHolder
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) {return when (viewType) {0 -> TextViewHolder(...)1 -> ImageViewHolder(...)}
}
4. 图片加载优化
fun bind(item: Item) {Glide.with(itemView).load(item.imageUrl).apply(RequestOptions().override(100, 100)) // 限制尺寸.into(imageView)
}override fun onViewRecycled() {Glide.with(itemView).clear(imageView) // 及时释放
}
五、事件监听实现
1. 点击事件处理
// 在 ViewHolder 中设置监听
class MyViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {init {itemView.setOnClickListener {val pos = adapterPositionif (pos != RecyclerView.NO_POSITION) {// 通过接口回调事件listener?.onItemClick(pos)}}}
}// 定义回调接口
interface OnItemClickListener {fun onItemClick(position: Int)
}
2. 长按事件
itemView.setOnLongClickListener {val pos = adapterPositionif (pos != RecyclerView.NO_POSITION) {listener?.onItemLongClick(pos)true} else false
}
3. 滑动监听
recyclerView.addOnScrollListener(object : RecyclerView.OnScrollListener() {override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {// dy > 0:向上滚动// dy < 0:向下滚动}override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) {when (newState) {RecyclerView.SCROLL_STATE_IDLE -> { /* 停止滚动 */ }RecyclerView.SCROLL_STATE_DRAGGING -> { /* 用户拖动 */ }RecyclerView.SCROLL_STATE_SETTLING -> { /* 惯性滑动 */ }}}
})
六、高级技巧
1. 嵌套滚动优化
<!-- 子RecyclerView设置 -->
android:nestedScrollingEnabled="false"
2. 预加载实现
recyclerView.addOnScrollListener(object : RecyclerView.OnScrollListener() {override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {val lastVisible = (layoutManager as LinearLayoutManager).findLastVisibleItemPosition()if (lastVisible > itemCount - 5) {// 触发预加载}}
})
3. 高效更新策略
// 使用 ListAdapter 自动处理差异更新
class MyAdapter : ListAdapter<Item, MyViewHolder>(DiffCallback()) {// 自动计算差异更新
}class DiffCallback : DiffUtil.ItemCallback<Item>() {override fun areItemsTheSame(old: Item, new: Item) = old.id == new.idoverride fun areContentsTheSame(old: Item, new: Item) = old == new
}
最佳实践总结
ViewHolder模式:必须使用避免重复findViewById
局部更新:优先使用DiffUtil/ListAdapter
资源释放:在onViewRecycled()中释放图片等资源
事件委托:通过接口回调代替在Adapter中处理逻辑
类型区分:多类型视图使用getItemViewType()
内存监控:使用Profiler检测滚动时的内存波动