如何在 Kotlin 中为 Android 的 RecyclerView 适配器初始化 viewHolder

Posted

技术标签:

【中文标题】如何在 Kotlin 中为 Android 的 RecyclerView 适配器初始化 viewHolder【英文标题】:How to initialize viewHolder in RecyclerView adapter for Android in Kotlin 【发布时间】:2022-01-13 18:25:19 【问题描述】:

我应该如何初始化 viewHolder?我有这个错误: 我想要做的是在 recyclerView 中获取选定的项目,但不使用 onClick 方法。当我得到这个选定的项目时,我需要显示 Toast 消息。项目是数据类。

进程:com.pors.coopreaderlast,PID:7862 kotlin.UninitializedPropertyAccessException:lateinit 属性 viewHolder 尚未初始化 在 com.pors.coopreaderlast.features.polozka.PolozkaAdapter.getViewHolder(PolozkaAdapter.kt:18) 在 com.pors.coopreaderlast.features.polozka.PolozkaAdapter.getCurrentItem(PolozkaAdapter.kt:46) 在 com.pors.coopreaderlast.features.polozka.PolozkaActivity.onStart(PolozkaActivity.kt:213)

这是针对在适配器中设置 viewHolder 的行: lateinit var viewHolder: PolozkaViewHolder

这是适配器

class PolozkaAdapter(val chosen_item: Int, private val listener: OnItemClickListener): ListAdapter<Polozka, PolozkaAdapter.PolozkaViewHolder>(DiffCallback())
    var selectedItemPosition: Int = chosen_item
    lateinit var viewHolder: PolozkaViewHolder

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): PolozkaViewHolder 
        val binding = PolozkyItemBinding.inflate(LayoutInflater.from(parent.context), parent, false)
        viewHolder = PolozkaViewHolder(binding)
        return viewHolder
    
    override fun onBindViewHolder(holder: PolozkaViewHolder, position: Int) 
        val currentItem = getItem(position)
        holder.bind(currentItem)
        if (selectedItemPosition == position)
            holder.itemView.setBackgroundColor(Color.parseColor("#DA745A"))
         else
            holder.itemView.setBackgroundColor(Color.TRANSPARENT)
        
    
    fun getCurrentItem(): Polozka = super.getItem(viewHolder.bindingAdapterPosition)    

    inner class PolozkaViewHolder(private val binding: PolozkyItemBinding): RecyclerView.ViewHolder(binding.root)
        init 
            binding.root.setOnClickListener
                val position = bindingAdapterPosition
                if (position != RecyclerView.NO_POSITION)
                    val item = getItem(position)
                    if (item != null)
                        listener.onItemClick(item, position)                        
                    
                
                notifyItemChanged(selectedItemPosition)                
                selectedItemPosition = bindingAdapterPosition
                notifyItemChanged(selectedItemPosition)
                        
        

        fun bind(polozkaPolozka: Polozka)
            binding.apply 
                tvKDE.text = polozkaPolozka.znacky
                tvREG.text = polozkaPolozka.reg
                tvVB.text = polozkaPolozka.veb.toString()  
            
        
        
    
    interface OnItemClickListener
        fun onItemClick(polozkaDoklad: Polozka, position: Int)        
    
    class DiffCallback: DiffUtil.ItemCallback<Polozka>()
        override fun areItemsTheSame(oldItem: Polozka, newItem: Polozka) =
            oldItem.pvp06pk == newItem.pvp06pk
        override fun areContentsTheSame(oldItem: Polozka, newItem: Polozka) =
            oldItem == newItem
    


这是 onStart 方法,但也可以在 onCreate 方法中。

 override fun onStart() 
        super.onStart()
        
        val polozkaAdapter = PolozkaAdapter(idPositionItem, this)
        val selectedItem = polozkaAdapter.getCurrentItem()        
    

【问题讨论】:

【参考方案1】:

您正在活动的onStart() 方法中调用polozkaAdapter.getCurrentItem()。此时您的适配器中不存在任何项目,因此 latenit var viewHolder 尚未初始化。

【讨论】:

【参考方案2】:

onCreateViewHolder 应始终返回 ViewHolder 的新实例,而不是单个实例。

【讨论】:

我该怎么做?如何返回 ViewHolder 的新实例?

以上是关于如何在 Kotlin 中为 Android 的 RecyclerView 适配器初始化 viewHolder的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Android Studio 中为 Kotlin Multiplatform 配置 iOS 应用程序?

使用 Kotlin 语言在 Android Studio 中为文本设置渐变颜色

如何在多平台 Android 模块中配置 Kotlin jvmTarget?

在 Kotlin 中为成功和错误处理两种不同的改造响应

Android Studio 3.1.3 - 未解决的参考:R - Kotlin

如何在intelliJ IDEA中为我现有的Kotlin项目生成build.gradle文件