Android RecyclerView点击项位置异常:显示错误或崩溃求助
解决RecyclerView点击位置错误的问题
核心错误修复
你的setOnItemClickListener方法存在赋值错误,导致点击事件的监听器根本没被正确设置,这是触发位置异常的直接原因:
fun setOnItemClickListener(listener: OnItemClickListener) { mListener = listener // 原代码是mListener = mListener,等于没赋值 }
其他优化建议
- 替换过时的位置获取方法
在ViewHolder的点击事件中,用bindingAdapterPosition替代adapterPosition(后者已被标记为Deprecated),同时添加无效位置判断,避免崩溃:
init { itemView.setOnClickListener { val position = bindingAdapterPosition if (position != RecyclerView.NO_POSITION) { listener.onItemClick(position) } } }
- 简化点击事件接口
你的OnItemClickListener不需要继承AdapterView.OnItemClickListener,两者属于不同组件体系,直接定义独立接口即可:
interface OnItemClickListener { fun onItemClick(position: Int) }
- 优化数据更新逻辑
如果列表数据会动态变化,避免直接调用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
相关产品推荐
相关产品推荐

