Несоответствия с RecyclerViews, ViewHolders и onBindViewHolder - PullRequest
0 голосов
/ 29 апреля 2020

Я изучаю / использую 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? Если я удаляю его, то я получаю ошибку компилятора «Unresolved reference: view» в onBindViewHolder в классе ViewAdapter. Почему? И, если я ** добавлю * декларацию val в AAA и CCC, Android Studio сообщит мне, что она не нужна, и предложит удалить ее для меня.

Далее, что-то странное onBindViewHolder функции ...

AAAListAdapter.kt (не отображается getItemCount или onCreateViewHolder):

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 отличается, я предполагаю, что эти два вопроса связаны, но я не знаю ....

(Пытался добавить тег android -onbindviewholder, но мне не хватает репутации.)

1 Ответ

1 голос
/ 29 апреля 2020

Сначала вы объявляете val / var внутри конструктора, чтобы использовать эти значения где-то в классе, не объявляя и не инициализируя его где-либо в вашем классе. Давайте возьмем в качестве примера: я хочу получить список в адаптере, я передам его в адаптер, а в адаптере я не буду тогда использовать 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"
}

Теперь перейдем к вашему варианту использования, видоискатель A и C идентичны, и B имеет представление объявлено, и вы используете его, но из кода в адаптере, я не думаю, что это необходимо, те же логики c можно было бы использовать в адаптере B, holder.itemView.something, holder.itemView в конечном счете это тот объект представления, который вы используете в A и C, поэтому для этого конкретного случая представление val не требуется.

Если вы его где-то используете, то добавьте весь код, там Я мог бы помочь вам понять, почему ViewHolder B отличается. Но из того, что вы написали, нет необходимости использовать val внутри конструктора.

...