RecyclerView 点击事件
处理 RecyclerView 中的项目点击和长按,将点击监听器传递给适配器,并在点击项目时导航到详情页面。
RecyclerView 点击事件 是 CoddyKit 上的免费 Android Academy 课时。 这是第 3 节课,共 6 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 Android Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 Android Academy 课程共包含 6 节课。
让列表项可点击
RecyclerView 没有像 ListView 那样内置的点击监听器。您需要在 Adapter 中添加点击监听器。
推荐的模式是:将 lambda(回调)传递给 Adapter 的构造函数。当用户点击某个列表项时,Adapter 会将选中的列表项传给 lambda,由 Activity 处理后续操作。
带点击回调的 Adapter
为 Adapter 添加一个 onItemClick lambda 参数:
class FruitAdapter(
private val fruits: List<Fruit>,
private val onItemClick: (Fruit) -> Unit
) : RecyclerView.Adapter<FruitAdapter.ViewHolder>() {
class ViewHolder(view: View) : RecyclerView.ViewHolder(view) {
val tvName: TextView = view.findViewById(R.id.tvName)
val tvCalories: TextView = view.findViewById(R.id.tvCalories)
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val view = LayoutInflater.from(parent.context)
.inflate(R.layout.item_fruit, parent, false)
return ViewHolder(view)
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
val fruit = fruits[position]
holder.tvName.text = fruit.name
holder.tvCalories.text = "${fruit.calories} kcal"
// Set click listener on the whole item
holder.itemView.setOnClickListener {
onItemClick(fruit)
}
}
override fun getItemCount() = fruits.size
}在 Activity 中处理点击
在 Activity 中传入一个用于跳转到详情页面的 lambda:
val adapter = FruitAdapter(fruits) { fruit ->
// Called when user taps a fruit
val intent = Intent(this, FruitDetailActivity::class.java)
intent.putExtra("FRUIT_NAME", fruit.name)
intent.putExtra("FRUIT_CALORIES", fruit.calories)
startActivity(intent)
}
binding.recyclerView.apply {
this.adapter = adapter
layoutManager = LinearLayoutManager(this@MainActivity)
}在详情页面接收数据
在详情 Activity 中读取附加数据:
class FruitDetailActivity : AppCompatActivity() {
private lateinit var binding: ActivityFruitDetailBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityFruitDetailBinding.inflate(layoutInflater)
setContentView(binding.root)
val name = intent.getStringExtra("FRUIT_NAME") ?: "Unknown"
val calories = intent.getIntExtra("FRUIT_CALORIES", 0)
binding.tvDetailName.text = name
binding.tvDetailCalories.text = "$calories kcal"
}
}使用 DiffUtil 高效更新
列表数据发生变化时,不要调用 notifyDataSetChanged()——它会重绘所有内容。请改用 DiffUtil:
- 计算新旧列表之间的最小差异
- 只为发生变化的列表项播放动画
- 带来更好的性能和用户体验
现代的做法是使用 ListAdapter,它会自动使用 DiffUtil。
使用 DiffUtil 的 ListAdapter
扩展 ListAdapter,即可自动为列表更新添加动画:
class FruitAdapter(
private val onItemClick: (Fruit) -> Unit
) : ListAdapter<Fruit, FruitAdapter.ViewHolder>(DIFF_CALLBACK) {
companion object {
val DIFF_CALLBACK = object : DiffUtil.ItemCallback<Fruit>() {
override fun areItemsTheSame(old: Fruit, new: Fruit) =
old.name == new.name
override fun areContentsTheSame(old: Fruit, new: Fruit) =
old == new // data class equals()
}
}
// ... ViewHolder and onCreateViewHolder same as before ...
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
val fruit = getItem(position) // use getItem(), not fruits[position]
holder.tvName.text = fruit.name
holder.itemView.setOnClickListener { onItemClick(fruit) }
}
}提交新列表
使用 ListAdapter 时,调用 submitList() 更新列表。DiffUtil 会自动处理动画:
// In Activity:
val adapter = FruitAdapter { fruit ->
// handle click
}
binding.recyclerView.adapter = adapter
// Initial data
adapter.submitList(fruits)
// Later, update with new data (e.g. after filtering):
val filtered = fruits.filter { it.calories < 100 }
adapter.submitList(filtered) // DiffUtil animates the change长按与上下文菜单
您还可以在 onBindViewHolder 中设置 setOnLongClickListener,以响应长按:
- 让监听器返回
true,以消费此事件 - 使用它显示删除或编辑对话框
- 或者使用
ItemTouchHelper实现滑动删除
添加列表项装饰
使用 DividerItemDecoration 在列表项之间添加视觉分隔:
binding.recyclerView.apply {
adapter = fruitAdapter
layoutManager = LinearLayoutManager(this@MainActivity)
addItemDecoration(
DividerItemDecoration(
this@MainActivity,
DividerItemDecoration.VERTICAL
)
)
}快速检查
在 RecyclerView Adapter 中处理列表项点击的推荐方式是什么?
回顾:RecyclerView 点击事件
现在,您可以构建交互式列表:
- 将 lambda 回调传递给 Adapter 构造函数
- 在
onBindViewHolder中调用holder.itemView.setOnClickListener - 通过 Intent 传递附加数据,跳转到详情页面
- 使用
ListAdapter+DiffUtil实现流畅的动画更新 - 调用
submitList()更新显示的数据
下一步:使用 SharedPreferences 在本地持久化数据。
常见问题解答
「RecyclerView 点击事件」课时是免费的吗?
是的 — 「RecyclerView 点击事件」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 Android Academy 课程的其余内容,请升级到 CoddyKit PRO。 Android Academy 课程共包含 6 节课。
「RecyclerView 点击事件」这节课中我会学到什么?
处理 RecyclerView 中的项目点击和长按,将点击监听器传递给适配器,并在点击项目时导航到详情页面。 你通过在浏览器中直接运行的动手代码来练习 Android Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。
学习 Android Academy 需要有经验吗?
无需任何先前经验。CoddyKit 上的 Android Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 3 节课,共 6 节。
「RecyclerView 点击事件」课时需要多长时间?
大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。
我能在这节 Android Academy 课中编写并运行代码吗?
能。每节 Android Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。
此课程中的所有课时
- Kotlin 集合
- RecyclerView 基础
- RecyclerView 点击事件
- SharedPreferences
- DataStore 偏好设置
- 适配器与 DiffUtil