首页 > 解决方案 > 谷歌 Android kotlin 代码实验室;我可以使用 RecyclerView.ViewHolder 替换所有 PhotoGridAdapter.MarsPropertyViewHolder 吗?

问题描述

我比较了两个 Google Codelabs,发现在如何规范化方面存在一些问题Android RecyclerView Codes

github链接如下:

  1. 第一个 CodeLabRecyclerView.ViewHolder用作类型

  2. 第二个 CodeLabPhotoGridAdapter.MarsPropertyViewHolder用作类型

  3. 我更改的 Second CodeLab 如下:

package com.example.android.marsrealestate.overview

//import android.widget.ListAdapter
import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.ListAdapter
import androidx.recyclerview.widget.RecyclerView
import com.example.android.marsrealestate.databinding.GridViewItemBinding
import com.example.android.marsrealestate.network.MarsProperty

class PhotoGridAdapter : ListAdapter<MarsProperty,
        RecyclerView.ViewHolder>(DiffCallback) {
    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
        return MarsPropertyViewHolder.from(parent)
    }

    override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
        val marsProperty = getItem(position)
        holder.bind(marsProperty) //FIXME:<<<------will cause error
    }

    class MarsPropertyViewHolder(private var binding:
                                 GridViewItemBinding) :
            RecyclerView.ViewHolder(binding.root) {
        fun bind(marsProperty: MarsProperty) {
            binding.property = marsProperty
            binding.executePendingBindings()
        }

        companion object {
            fun from(parent: ViewGroup): MarsPropertyViewHolder {
                val layoutInflater = LayoutInflater.from(parent.context)
                val binding = GridViewItemBinding.inflate(layoutInflater)
                return MarsPropertyViewHolder(binding)
            }
        }
    }

    companion object DiffCallback : DiffUtil.ItemCallback<MarsProperty>() {
        override fun areItemsTheSame(oldItem: MarsProperty, newItem: MarsProperty): Boolean {
            return oldItem.id == newItem.id
        }

        override fun areContentsTheSame(oldItem: MarsProperty, newItem: MarsProperty): Boolean {
            return oldItem == newItem
        }
    }
}

问题:

我尝试将所有第二个代码从PhotoGridAdapter.MarsPropertyViewHolder(Customize ViewHolder) 替换为 RecyclerView.ViewHolder,但会导致错误。

错误如下: PhotoGridAdapter > onBindViewHolder > holder.bind未找到。

为什么,第一个 Codelab 工作,但第二个 Codelab 不工作?

标签: androidkotlinandroid-recyclerview

解决方案


RecyclerView.ViewHolder没有bind方法,它只存在于您的 customMarsPropertyViewHolder中。如果您仍想声明 common RecyclerView.ViewHolder,但想使用 extendedMarsPropertyViewHolder那么您必须按以下方式转换 holder:

(holder as MarsPropertyViewHolder).bind(marsProperty)

请放心,onCreateViewHolder它将永远返回MarsPropertyViewHolder,如果没有,那么您可能会ClassCastException进入onBindViewHolder。您可以选择使用一些检查:if(holder is MarsPropertyViewHolder) {...}


推荐阅读