You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

RecyclerView、ViewHolder与onBindViewHolder使用疑问

嘿,这两个问题其实本质上是和Kotlin构造函数的属性规则、以及RecyclerView.ViewHolder的父类设计有关,咱们一个个拆解清楚:

疑问一:为什么BBBViewHolder的view要加val?移除就报错?

咱们从Kotlin的构造函数逻辑说起:

  • 当你在构造参数前加val或var时,这个参数会自动成为类的成员属性,外部可以通过类的实例直接访问;如果不加,它只是构造函数内部的临时参数,类的外部完全看不到这个参数的存在。
  • 你的BBBViewHolder里写了val view: View,所以这个view变成了BBBViewHolder的成员属性,在onBindViewHolder里holder.view才能正常访问。一旦把val去掉,这个view就只是构造函数的局部参数,BBBViewHolder类里没有这个成员属性,编译器自然会报“Unresolved reference: view”——它找不到这个属性。
  • 再看AAA和CCCViewHolder:它们的构造参数view: View没有加val/var,所以没有成为类的成员。Android Studio提示加val多余,是因为RecyclerView.ViewHolder这个父类本身就已经把你传入的view存成了公共成员属性itemView!如果你给AAA/CCC的view加val,就相当于在子类里重复声明了一个和父类itemView指向同一个对象的属性,完全没必要,所以AS会建议你移除。

疑问二:为什么有的用holder.view,有的用holder.itemView?怎么统一代码风格?

其实这两个属性指向的是同一个View实例:

  • 你在BBBViewHolder里声明的val view: View,就是你传给父类构造函数的那个view;而父类RecyclerView.ViewHolder会把这个view赋值给自己的itemView属性。所以holder.view和holder.itemView是同一个东西,只是访问路径不同。
  • AAA/CCCViewHolder因为没有自己声明view成员,所以只能用父类提供的itemView来访问布局视图。

要统一代码风格非常简单:全部改用holder.itemView即可,不需要在ViewHolder里声明自己的view成员。这样所有ViewHolder的写法都能保持一致,而且完全符合RecyclerView的设计规范——父类已经帮你托管了这个view实例,没必要自己再存一遍。

优化后的BBBViewHolder可以改成这样:

class BBBViewHolder(view: View, var bbb: BBB? = null) : RecyclerView.ViewHolder(view) {...}

对应的onBindViewHolder代码调整为:

override fun onBindViewHolder(holder: BBBViewHolder, position: Int) {
    val bbb = bbbList[position]
    holder.itemView.bTextView.text = "BBB"
    holder.bbb = bbb
}

内容的提问来源于stack exchange,提问作者Zonker.in.Geneva

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.07 14:27:48