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

Android RecyclerView点击项位置异常:显示错误或崩溃求助

解决RecyclerView点击位置错误的问题

核心错误修复

你的setOnItemClickListener方法存在赋值错误,导致点击事件的监听器根本没被正确设置,这是触发位置异常的直接原因:

fun setOnItemClickListener(listener: OnItemClickListener) {
    mListener = listener // 原代码是mListener = mListener,等于没赋值
}

其他优化建议

  1. 替换过时的位置获取方法
    在ViewHolder的点击事件中,用bindingAdapterPosition替代adapterPosition(后者已被标记为Deprecated),同时添加无效位置判断,避免崩溃:
init {
    itemView.setOnClickListener {
        val position = bindingAdapterPosition
        if (position != RecyclerView.NO_POSITION) {
            listener.onItemClick(position)
        }
    }
}
  1. 简化点击事件接口
    你的OnItemClickListener不需要继承AdapterView.OnItemClickListener,两者属于不同组件体系,直接定义独立接口即可:
interface OnItemClickListener {
    fun onItemClick(position: Int)
}
  1. 优化数据更新逻辑
    如果列表数据会动态变化,避免直接调用notifyDataSetChanged(),尽量使用notifyItemChanged()、notifyItemInserted()这类精确的通知方法,帮助RecyclerView更准确维护项的位置信息。

修改后的完整Adapter代码

class MyAdapter(private val mList: ArrayList<MyModel>) : RecyclerView.Adapter<MyAdapter.ViewHolder>() {

    private lateinit var mListener: OnItemClickListener

    interface OnItemClickListener {
        fun onItemClick(position: Int)
    }

    fun setOnItemClickListener(listener: OnItemClickListener) {
        mListener = listener
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
        val view = LayoutInflater.from(parent.context).inflate(R.layout.item_all_brands, parent, false)
        return ViewHolder(view, mListener)
    }

    @SuppressLint("SetTextI18n")
    @RequiresApi(Build.VERSION_CODES.N)
    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
        val item = mList[position]
        holder.ivBrandImage.setImageResource(item.image)
        holder.tvBrandName.text = item.name

        holder.tvBrandName.isSelected = true
        holder.tvBrandName.setSingleLine()
    }

    override fun getItemId(position: Int): Long {
        return position.toLong()
    }

    override fun getItemCount(): Int {
        return mList.size
    }

    class ViewHolder(ItemView: View, listener: OnItemClickListener) :
        RecyclerView.ViewHolder(ItemView) {
        val ivBrandImage: ImageView = itemView.findViewById(R.id.ivBrandImage)
        val tvBrandName: TextView = itemView.findViewById(R.id.tvBrandName)

        init {
            itemView.setOnClickListener {
                val position = bindingAdapterPosition
                if (position != RecyclerView.NO_POSITION) {
                    listener.onItemClick(position)
                }
            }
        }
    }
}

内容的提问来源于stack exchange,提问作者prince

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 00:30:57