学而实习之 不亦乐乎

Android 中为 RecyclerView 实现 Item 点击事件

2022-12-20 09:37:48

RecyclerView 没有像 ListView 那样直接提供 OnItemClick 或者 OnItemLongClick 等事件回调接口,需要自己来注册监听,但这也增强其灵活性。一种方法是在 Adapter 中的为其 ViewHolder 添加点击事件,另一种方法是通过自定义监听接口进行实现。

一、在 Adapter 中实现事件监听

在Adapter中实现的ViewHolder类中,根据需求,给item或者item中的控件设置点击监听事件即可

    static class ViewHolder extends RecyclerView.ViewHolder {

        private ImageView iv_p;
        private TextView tv_title;

        public ViewHolder(View itemView) {
            super(itemView);
            iv_p = (ImageView) itemView.findViewById(R.id.iv_p);
            tv_title = (TextView) itemView.findViewById(R.id.tv_title);
            
            //给itemView设置的点击监听事件
            itemView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    //编写对应的逻辑
                }
            });
            
            //给itemView中的某个ImageView设置点击事件
            iv_p.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    //编写对应的逻辑
                }
            });
        }
    }

二、通过自定义监听接口实现监听事件

1、定义监听接口

接口定义如下:

public interface onRecyclerViewItemClickListener {
    // 方法里的参数可根据需要进行调整
    void onItemClick(RecyclerView parent, View view, int position);
    void onItemLongClick(RecyclerView parent, View view, int position);
}

也可以单独弄一个定义接口文件,一个接口管理一个监听事件回调,这样更规范。事件参数也可以根据需要进行调整,如果没有特别需要,只要拿到item索引就够了。定义如下:

public interface IAdapter {
    /*
    * Item 单击事件后续处理
    */
    interface OnRVItemClickListener {
        void onClick(int position);
    }

    /*
    * Item 长按事件后续处理
    */
    interface OnRVItemLongClickListener {
        boolean onLongClick(int position);
    }

    /*
    * Item 移除事件后续处理
    */
    interface OnRVItemRemoveListener{
        void onRemove(int position);
    }
}

2、修改Adapter

初始化接口事件

    //初使化自定义的接口,接口定义在哪个包下就会把哪个包名也引入进来,只是名字长点,不影响使用
    private onRecyclerViewItemClickListener onRecyclerViewItemClickListener;
    //为了方便接口函数传值,这里把RecyclerView控件拉出来,如果接口方法参数列表里没有,可以不用写
    private RecyclerView rvParent;

绑定接口回调事件
    //定义一个公用方法,可以在Activity中来绑定接口事件

    public void setOnItemClickListener(pub.onRecyclerViewItemClickListener onRecyclerViewItemClickListener) {
        this.onRecyclerViewItemClickListener = onRecyclerViewItemClickListener;
    }

3、绑定控件监听

这里有两种实现方式

【1】直接给控件绑定监听事件

具体的事件内容改为调用监听接口事件的方法即可,别忘了把参数传进去给外部调用时使用,推荐使用这种简单写法。

 @Override
 public void onBindViewHolder(@NonNull viewHolder holder, int position) {
     holder.bind(lstCharges.get(position));
     holder.mView.getRoot().setOnClickListener(view -> itemClickListener.onClick(position));
     holder.mView.getRoot().setOnLongClickListener(view -> itemLongClickListener.onLongClick(position));  
 }

【2】继承 View.OnClickListener

另一个就是在你的类名之后 implements 一个 View.OnClickListener 然后重写 onClick 方法,使用这种方法,在此获取不到当前的索引位置,可以定义一个 int 公用变量来存储更新,也可以如上面把 RecyclerView 拉出来,通过当前view来查找索引位置。代码如下:

public class FileAdapter extends RecyclerView.Adapter<FileAdapter.myViewHolder> implements View.OnClickListener {
    ...
    private pub.onRecyclerViewItemClickListener onRecyclerViewItemClickListener;
    private RecyclerView rvParent;

    ...
    @NonNull
    @Override
    public myViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        //指定一个父控件
        rvParent = (RecyclerView) parent;
        View view = LayoutInflater.from(mContext).inflate(R.layout.file_manager_item, parent, false);
        //绑定监听点击事件
        view.setOnClickListener(this);
        return new myViewHolder(view, mContext);
    }

    ...
    //重载点击事件,指定点击事件时执行自定义的onItemClick
    @Override
    public void onClick(View view) {
        int position = rvParent.getChildAdapterPosition(view);
        if (onRecyclerViewItemClickListener != null)
            onRecyclerViewItemClickListener.onItemClick(rvParent, view, position);
    }

    ...
    //实例化自定义接口
    public void setOnItemClickListener(onRecyclerViewItemClickListener onRecyclerViewItemClickListener) {
        this.onRecyclerViewItemClickListener = onRecyclerViewItemClickListener;
    }
}

4、使用

在 Activity 中实现事件监听

fileAdapter.setOnItemClickListener(new pub.onRecyclerViewItemClickListener() {
        @Override
        public void onItemClick(RecyclerView parent, View view, int position) {
            //自定义点击后的功能事件 ...
            /* 此处代码仅供参考,演示怎样调用当前item的信息
            mView.tvFmPath.setText(lstFiles.get(position).getFilePath());
            getPath(lstFiles.get(position).getFilePath());
            fileAdapter.notifyDataSetChanged();
            */
        }

        @Override
        public void onItemLongClick(RecyclerView parent, View view, int position) {
            //自定义长按后的功能事件 ...
        }
    });