为 RecyclerView 添加 OnItemClickListener

来源:互联网 发布:人工智能的未来展望 编辑:程序博客网 时间:2024/05/16 08:13

由于 RecyclerView 没有提供 OnItemClickListener ,只提供了一个 OnItemTouchListener ,导致网上各种方式实现 OnItemClickListener ,看了几篇 blog 也没有符合我口味的代码…还是自己实现一遍吧。

1.自定义 RecyclerView

自定义 RecyclerView 直接继承 v7 的 RecyclerView 即可,不需要复杂的代码,以后统一使用该 RecyclerView,代码如下:

    public class CustomRecyclerView extends RecyclerView {    private Context context;    private CustomRecyclerViewDivider customRecyclerViewDivider;// ItemView 的分割线,不是本文重点,请自动忽略    private List<OnItemClickListener> onItemClickListenerList;// OnItemClickListener 用 add 的方式比较好    public CustomRecyclerView(Context context) {        this(context, null);    }    public CustomRecyclerView(Context context, @Nullable AttributeSet attrs) {        this(context, attrs, 0);    }    public CustomRecyclerView(Context context, @Nullable AttributeSet attrs, int defStyle) {        super(context, attrs, defStyle);        init(context);    }    /**     * 如果没有其他操作,默认添加水平分割线,竖直分布     * 仿 ListView     *     * @param context     */    private void init(Context context) {        this.context = context;        onItemClickListenerList = new ArrayList<>();        LinearLayoutManager manager = new LinearLayoutManager(context);        setHasFixedSize(true);        customRecyclerViewDivider = new CustomRecyclerViewDivider(new ColorDrawable(0xeeeeeeee), OrientationHelper.VERTICAL);        //单位:px        customRecyclerViewDivider.setMargin(0, 0, 0, 0);        customRecyclerViewDivider.setHeight(ConvertTool.dp2px(1));        addItemDecoration(customRecyclerViewDivider);        setLayoutManager(manager);    }    @Override    public void setAdapter(Adapter adapter) {        super.setAdapter(adapter);    }    public void addOnItemClickListener(OnItemClickListener onItemClickListener) {        if (null != onItemClickListener) {            onItemClickListenerList.add(onItemClickListener);        }    }    /**     * 清空所有 onItemClickListener     * @param onItemClickListener     */    public void clearAllOnItemClickListeners() {        onItemClickListenerList.clear();    }    /**     * 自定义 OnItemClickListener     */    public static abstract class OnItemClickListener {        public void onClick(View view, int position) {        }    }    public List<OnItemClickListener> getOnItemClickListenerList() {        return onItemClickListenerList;    }}

2.自定义 OnClickListener

为了更简洁地实现 OnItemClickListener ,我们可以为每个 ItemView 设置 OnclickListener ,由于 OnItemClickListener 需要 view 和 position ,所以自定义一个 OnclickListener 是最好的选择,其代码如下:

    // CustomOnClickListener 在我的代码里被多处使用,所以使用了泛型,当用于     // RecyclerView 时,需要将 T 传入 Integer 以记录点击的位置,即: position    public class CustomOnClickListener<T> implements View.OnClickListener {    private T t;    public CustomOnClickListener() {    }    public CustomOnClickListener(T t) {        this.t = t;    }    @Override    public void onClick(View v) {        TraceKeeper.addTrace(v);        this.onClick(v , t);    }    public void onClick(View view, T t) {    }    public void setT(T t) {        this.t = t;    }    }

3.自定义 Adapter

要使 CustomRecyclerView 可以通过 addOnItemClickListener 设置监听器,我们需要对 v7 提供的 RecyclerView.Adapter 略微改造一下,代码如下:

    public abstract class RecyclereViewBaseAdapter<T extends RecyclereViewBaseAdapter.BaseViewHolder>        extends RecyclerView.Adapter<T> {    private CustomRecyclerView customRecyclerView;    // 用于保存 customRecyclerView 中的 OnItemClickListener    private List<CustomRecyclerView.OnItemClickListener> onItemClickListenerList;    @Override    public T onCreateViewHolder(ViewGroup parent, int viewType) {        if (null != parent) {            // 这里执行一次即可            customRecyclerView = (CustomRecyclerView) parent;            onItemClickListenerList = customRecyclerView.getOnItemClickListenerList();        }        return null;    }    @Override    public void onBindViewHolder(T holder, int position) {        // 由于 RecyclerView 的 ItemView 会被复用,所以显示新的 ItemView 时都需要更新        // ItemView OnClickListener 的状态,确保 position 是当前位置        holder.getCustomOnClickListener().setT(position);    }    public class BaseViewHolder extends RecyclerView.ViewHolder {        private View itemView;        // 确保每个 ItemView 都有 CustomOnClickListener ,由于每个 View 只存在一个 OnClickListener 所以,使用了         // OnItemClickListener 就不要为 ItemView 再设置 OnClickListener了。基于 RecyclerView 的原理(不做展开),        // 在这里设置 CustomOnClickListener 是最好的选择。        private CustomOnClickListener customOnClickListener = new CustomOnClickListener<Integer>(0) {            @Override            public void onClick(View view, Integer integer) {                super.onClick(view, integer);                if (null != onItemClickListenerList && onItemClickListenerList.size() > 0) {                    for (CustomRecyclerView.OnItemClickListener onItemClickListener : onItemClickListenerList) {                        onItemClickListener.onClick(view, integer);                    }                }            }        };        public BaseViewHolder(View itemView) {            super(itemView);            this.itemView = itemView;            this.itemView.setOnClickListener(customOnClickListener);        }        public CustomOnClickListener getCustomOnClickListener() {            return customOnClickListener;        }    }}

4.OnItemClickListener 的使用

自定义的 RecyclerView 设置 OnItemClickListener 和 ListView 没有区别,可以直接设置:

    // 导包时注意     onItemClickListener 继承的是 CustomRecyclerView.OnItemClickListener    customRecyclerView .addOnItemClickListener(onItemClickListener);

另外,extends RecyclereViewBaseAdapter 时,不要忘记各个 method 中要 super(…) .

1 0