为 RecyclerView 增加监听以及数据混乱的小坑

本文介绍如何为RecyclerView添加点击和长按监听,并详细说明了RecyclerView.Adapter提供的局部刷新方法及其使用注意事项,帮助开发者更好地优化应用程序性能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

为 RecyclerView增加监听

  1. 在实现好的MyAdapter中写内部接口:

    public void setOnItemLongClickListener(OnItemLongClickListener onItemLongClickListener) {
        this.onItemLongClickListener = onItemLongClickListener;
    }
    public void setOnItemClickListener(OnItemClickListener onItemClickListener) {
        this.onItemClickListener = onItemClickListener;
    }
    //--点击监听
    public interface OnItemClickListener {
        void onItemClick(View view, int pos);
    }
    
    //--长按监听
    public interface OnItemLongClickListener {
        void onItemLongClick(View view, int position);
    }
  2. 继续在MyAdapter中增加以下代码:

    public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> {
    
    private OnItemClickListener onItemClickListener;
    private OnItemLongClickListener onItemLongClickListener;
                ......
    
    @Override
    public void onBindViewHolder(ViewHolder holder, int position) {
    
        final int pos = holder.getLayoutPosition();
        holder.mTextView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if (onItemClickListener != null)
                    onItemClickListener.onItemClick(view, pos);
            }
        });
    
        holder.mTextView.setOnLongClickListener(new View.OnLongClickListener() {
            @Override
            public boolean onLongClick(View view) {
                if (onItemLongClickListener != null) {
                    onItemLongClickListener.onItemLongClick(view, pos);
                }
                return true;
            }
        });
    
    }
    }

    以上代码是接口一般的写法,没什么难度,需要注意的是几个局部刷新的方法。

  3. 为了将性能提升至极致,RecyclerView的视图中某个item数据变化时,RecyclerView.Adapter提供几个局部刷新数据视图的方法:

    //该方法用于当增加一个数据的时候,position表示新增数据显示的位置
    final void notifyItemInserted(int position)
    
    //该方法用于删除一个数据的时候,position表示数据删除的位置
    final void notifyItemRemoved(int position)
    
    //该方法表示所在position对应的item位置不会改变,但是该item内容发生变化
    final void notifyItemChanged(int position)
    
    //当然也还有老方法全部刷新,该方法一般用于:适配器之前装载的数据大部分已经过时了,需要重新更新数据调用  
    //该方法的时候,recyclerView会重新计算子item及所有子item重新布局,简单但是效率低并且不带默认的动画:
    
    final void notifyDataSetChanged()

    出于效率考虑,官方建议用更加精确的方法(比如上面三个方法)来取代这个方法:
    ①.在RecyclerView.ViewHolder中说提及position(下标)时,有两种情况:
        i.由ViewHolder的 getLayoutPosition() 方法返回的,是视图中 itemView 的下标
        i.由ViewHolder的 getAdapterPosition() 方法返回的,是Adapter数据集(如ArrayList) data元素 的下标.
    正常时,第几个itemView上显示地接个data的内容,两者一一对应。

②. 但是在使用局部刷新的几个方法时要注意,我们知道,一个数据集比如ArrayList,移除某个元素时,它后面的元素会向前填充,所以后面每个元素的下标都会减一;

③. 然而对于 getLayoutPosition() 来讲,当我们用 notifyItemInserted 方法移除掉一个itemView时,视图上看后面的itemView会挤上去,但是它们的下标是没有变的。比如十个itemView(下标0到9)我用 notifyItemInserted 方法移除了第三个, 那么视图中剩下的itemView的下标就是(0,1和3到9), 这时候再去对数据集调用remove(9)的话势必会抛出数组越界异常;

④. 因此在每次刷新后,要使用 notifyItemRangeChanged(int positionStart,int itemCount) 调整itemView的下标,使其和数据集的下标始终是一一对应。其中 positionStart 是第一个改变的itemView下标,itemCount指它后面下标也需要改变的itemView个数

以上是RecyclerView的初级具体使用方法。

上一篇: 给RecyclerView添加分割线的步骤
上上篇:RecyclerView的具体使用

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值