与 RecyclerViews、ViewHolders 和 onBindViewHolder 的不一致

Inconsistencies with RecyclerViews, ViewHolders and onBindViewHolder

我是 learning/using RecyclerView,虽然我的应用程序可以正常工作(目前!),但有两件事我不明白。

这是我的 ViewHolder 声明:

class AAAViewHolder (    view: View, var aaa: AAA? = null) : RecyclerView.ViewHolder (view) {...}
class BBBViewHolder (val view: View, var bbb: BBB? = null) : RecyclerView.ViewHolder (view) {...}
class CCCViewHolder (    view: View, var ccc: CCC? = null) : RecyclerView.ViewHolder (view) {...}

为什么 BBBViewHolder 有多余的 val?如果我删除它,那么我会在 ViewAdapter class 中的 onBindViewHolder 中收到“未解析的引用:视图”编译器错误。为什么?而且,如果我*添加 AAA 和 CCC 的 val 声明,Android Studio 会告诉我它不需要并为我删除它。

接下来,onBindViewHolder 函数有些奇怪。

AAAListAdapter.kt(不显示 getItemCountonCreateViewHolder):

class AAAListAdapter : RecyclerView.Adapter<AAAViewHolder>() {
    override fun onBindViewHolder(holder: AAAViewHolder, position: Int) {
        val aaa = aaaList[position]
        holder.itemView.aTextView.text = "AAA"
        holder.aaa = aaa
    }
}

BBBListAdapter.kt

class BBBListAdapter : RecyclerView.Adapter<BBBViewHolder>() {
    override fun onBindViewHolder(holder: BBBViewHolder, position: Int) {
        val bbb = bbbList[position]
        holder.view.bTextView.text = "BBB"
        holder.bbb = bbb
    }
}

CCCListAdapter.kt

class CCCListAdapter : RecyclerView.Adapter<CCCViewHolder>() {
    override fun onBindViewHolder(holder: CCCViewHolder, position: Int) {
        val ccc = cccList[position]
        holder.itemView.cTextView.text = "CCC"
        holder.ccc = ccc
    }
}

代码几乎相同,除了为什么 BBBListAdapter 引用 holder.view,而其他两个引用 holder.itemView?这些属性在哪里声明?我能控制吗?我更希望它们是一样的。

看到 A 和 C 如何表现相同但 B 不同,我猜这两个问题是相关的,但我不知道。

首先,您在构造函数中声明 val/var 以在 class 中的某处使用这些值,而无需在 class 中的任何位置声明或初始化它。举个例子,我想要一个适配器列表,我会在适配器中传递它,然后在适配器中我不会使用 val/var 并且我不能使用它,除非我事先创建一个变量并在内部初始化它它的默认构造函数。

class A() {
      lateinit var view : View
      constructor(view : View) {
       this.view = view
      }
     view.textView.text = "Redundant Code"
} 

现在您可以通过在构造函数本身中声明它来减少它。

class A(val view : View) {
      view.textView.text = "Easy way"
}

现在来看你的用例,viewholder A 和 C 是相同的,B 声明了视图并且你正在使用它,但是从适配器中的代码我认为没有必要,相同的逻辑可以已在适配器 B 中使用,holder.itemView.something,holder.itemView 最终是您在 A 和 C 中使用的视图对象,因此在特定情况下不需要 val view。

如果您在某处使用它,然后添加整个代码,我也许可以帮助您了解为什么 ViewHolder B 不同。但是从您发布的内容来看,不需要在构造函数中使用 val 。