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

Kotlin从Synthetics转ViewBinding时Adapter的binding未初始化报错如何解决

错误根因

你当前的代码存在两个核心问题导致报错:

  1. 你将MessageItemBinding声明为Adapter的全局属性,违背了RecyclerView的复用逻辑:每个列表项对应独立的Binding实例,全局唯一的Binding实例既无法匹配多个列表项的渲染需求,也没有在任何位置执行初始化操作,所以抛出lateinit未初始化的异常。
  2. 代码中同时混用findViewById和ViewBinding,没有完全发挥ViewBinding的优势。
修复方案

将Binding实例放到ViewHolder中托管,在创建ViewHolder时完成Binding初始化,修改后的完整代码如下:

class MessagingAdapter: RecyclerView.Adapter<MessagingAdapter.MessageViewHolder>() {

    var messagesList = mutableListOf<Message>()

    // 将binding作为ViewHolder的成员变量,每个ViewHolder对应一个独立的binding实例
    inner class MessageViewHolder(val binding: MessageItemBinding) : RecyclerView.ViewHolder(binding.root) {
        init {
            itemView.setOnClickListener {
                //Remove message on the item clicked
                messagesList.removeAt(adapterPosition)
                notifyItemRemoved(adapterPosition)
            }
        }
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MessageViewHolder {
        // 直接通过ViewBinding的inflate方法创建实例,完成初始化
        val binding = MessageItemBinding.inflate(LayoutInflater.from(parent.context), parent, false)
        return MessageViewHolder(binding)
    }

    override fun getItemCount(): Int = messagesList.size

    @SuppressLint("SetTextI18n")
    override fun onBindViewHolder(holder: MessageViewHolder, position: Int) {
        val currentMessage = messagesList[position]
        val binding = holder.binding

        when (currentMessage.id) {
            SEND_ID -> {
                binding.tvMessage.apply {
                    text = currentMessage.message
                    visibility = View.VISIBLE
                }
                binding.tvBotMessage.visibility = View.GONE
            }
            RECEIVE_ID -> {
                binding.tvBotMessage.apply {
                    text = currentMessage.message
                    visibility = View.VISIBLE
                }
                binding.tvMessage.visibility = View.GONE
            }
        }
    }

    fun insertMessage(message: Message) {
        this.messagesList.add(message)
        notifyItemInserted(messagesList.size)
    }
}
修改说明
  • 移除了Adapter全局的lateinit var binding声明,改为将Binding实例作为ViewHolder的成员变量,匹配RecyclerView的复用逻辑
  • 在onCreateViewHolder中直接通过MessageItemBinding.inflate完成Binding实例的创建和初始化,不需要单独inflate布局
  • 移除了所有findViewById调用,直接通过ViewHolder持有的Binding实例访问布局控件,避免空指针风险同时提升性能

内容的提问来源于stack exchange,提问作者Jeffrey Kurdt Dreo

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.18 15:54:05