RecyclerView使用(三)

RecyclerView并没有像 ListView 提供一些关于 Item 的某种事件监听,唯一的就是 addOnItemTouchListener,原因可以看这个Google为什么不为Android中的RecyclerView添加Item的点击监听器?
所以我们需要自己来添加监听事件,网上大概有两种方法,以下来介绍这两种方法

第一种方法

先看完整代码在讲解。

public class OnClickAdapter extends RecyclerView.Adapter {

    private ArrayList list;//要显示的数据
    private Context context;
    private OnRecyclerViewItemClickListener onItemClickListener;//点击的接口
    private OnRecyclerViewItemLongClickListener onItemLongClickListener;//长按的接口

    /*
    多参的构造方法
     */
    public OnClickAdapter(ArrayList list, Context context) {
        this.list = list;
        this.context = context;
    }


    @Override
    public OnClickViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {

        View view = LayoutInflater.from(context).inflate(R.layout.main_item,parent,false);
        OnClickViewHolder holder = new OnClickViewHolder(view);
        return holder;
    }
    //                Toast.makeText(context,"这是textView的点击事件",Toast.LENGTH_SHORT).show();
    @Override
    public void onBindViewHolder(OnClickViewHolder holder, final int position) {
        holder.tvShow.setText(list.get(position));
        holder.tvShow.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                onItemClickListener.OnItemClick(position);
            }
        });
//
        holder.tvShow.setOnLongClickListener(new View.OnLongClickListener() {
            @Override
            public boolean onLongClick(View v) {
                onItemLongClickListener.OnItemLongClick(position);
                return true;
            }
        });
    }

    @Override
    public int getItemCount() {
        return list.size();
    }

    public class OnClickViewHolder extends RecyclerView.ViewHolder {

        TextView tvShow;

        public OnClickViewHolder(View itemView) {
            super(itemView);
            tvShow = (TextView) itemView.findViewById(R.id.tv_show);
        }
    }

    /*
    暴露出去的点击事件的方法
     */
    public void setOnItemClickListener(OnRecyclerViewItemClickListener onItemClickListener){
        this.onItemClickListener = onItemClickListener;
    }

    /*
    点击要实现的接口
     */
    public interface OnRecyclerViewItemClickListener{
        //接口中实现具体操作的抽象方法
        public abstract void OnItemClick(int itemPosition);
    }

    /*
    暴露出去的长按事件的方法
     */
    public void setOnItemLongClickListener(OnRecyclerViewItemLongClickListener onItemLongClickListener){
        this.onItemLongClickListener = onItemLongClickListener;
    }

    /*
    长按要实现的接口
     */
    public interface OnRecyclerViewItemLongClickListener{
        //接口中实现具体操作的抽象方法
        public abstract void OnItemLongClick(int itemPosition);
    }

}

在Activity中调用

adapter.setOnItemClickListener(new OnClickAdapter.OnRecyclerViewItemClickListener() {
    @Override
    public void OnItemClick(int itemPosition) {
        Toast.makeText(OnClickActivity.this,"点击"+list.get(itemPosition),Toast.LENGTH_SHORT).show();
    }
});
adapter.setOnItemLongClickListener(new OnClickAdapter.OnRecyclerViewItemLongClickListener() {
    @Override
    public void OnItemLongClick(int itemPosition) {
        Toast.makeText(OnClickActivity.this,"长按"+list.get(itemPosition),Toast.LENGTH_SHORT).show();
    }
});

首先需要一个接口(相当于OnClickListener接口),里面是写一个你需要实现操作的方法(onClick方法),再写一个暴露的方法(相当于setOnClickListener方法),通过这个方法将接口传进来,最后通过在具体你需要点击的监听事件里面,通过这个接口来调用抽象方法。
如果实在很难理解,只要记住你写Button点击事件,需要什么就设计什么。

第二种方法

这种方法是通过那个唯一addOnItemTouchListener的方法,同上先是完整代码

public abstract class OnRecyclerItemClickListener implements RecyclerView.OnItemTouchListener {

    private GestureDetectorCompat mGestureDetector;//处理手势的类
    private RecyclerView recyclerView;

    public OnRecyclerItemClickListener(RecyclerView recyclerView){
        this.recyclerView = recyclerView;
        mGestureDetector = new GestureDetectorCompat(recyclerView.getContext(),new ItemTouchHelperGestureListener());
    }
    //暴露的点击方法
    public abstract void onItemClick(RecyclerView.ViewHolder vh);
    //暴露的长按方法
    public abstract void onItemLongClick(RecyclerView.ViewHolder vh);
    
    //事件拦截
    @Override
    public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) {
        mGestureDetector.onTouchEvent(e);
        return false;
    }
    //事件处理
    @Override
    public void onTouchEvent(RecyclerView rv, MotionEvent e) {
        mGestureDetector.onTouchEvent(e);
    }
    //处理触摸事件冲突
    @Override
    public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {
    }
    
    //处理手势的类
    private class ItemTouchHelperGestureListener extends GestureDetector.SimpleOnGestureListener {
        //点击事件
        @Override
        public boolean onSingleTapUp(MotionEvent e) {
            View child = recyclerView.findChildViewUnder(e.getX(), e.getY());
            if (child != null) {
                RecyclerView.ViewHolder vh = recyclerView.getChildViewHolder(child);
                onItemClick(vh);
            }
            return true;
        }

        //长按事件
        @Override
        public void onLongPress(MotionEvent e) {
            View child = recyclerView.findChildViewUnder(e.getX(), e.getY());
            if (child != null) {
                RecyclerView.ViewHolder vh = recyclerView.getChildViewHolder(child);
                onItemLongClick(vh);
            }
        }
    }
    
}

在Activity中调用

myRecyclerView.addOnItemTouchListener(new OnRecyclerItemClickListener(myRecyclerView) {
    @Override
    public void onItemClick(RecyclerView.ViewHolder vh) {
        Toast.makeText(OnClickActivity.this,"点击"+list.get(vh.getLayoutPosition()),Toast.LENGTH_SHORT).show();
    }

    @Override
    public void onItemLongClick(RecyclerView.ViewHolder vh) {
        Toast.makeText(OnClickActivity.this,"长按"+list.get(vh.getLayoutPosition()),Toast.LENGTH_SHORT).show();
    }
});

首先addOnItemTouchListener是一个添加触摸监听的方法,这样就可以手势来监听一个点击手势,然后就需要新建一个GestureDetector.SimpleOnGestureListener来帮助判断点击还是长按,最后还需要来判断你到底点击是哪一个Item,所以使用findChildViewUnder方法可以通过点击的坐标来判断item,再使用另一个方法getChildViewHolder方法,可以获得该item的ViewHolder,将其传给暴露方法。
感谢这位作者,详细的查看RecyclerView无法添加onItemClickListener最佳的高效解决方案
但是有一个缺点,它不太好处理itemView里面的监听事件,会有所冲突。

RecyclerView的系列的文章

  • 第一篇RecyclerView的基本使用 RecyclerView使用(一)
  • 第二篇有关多种Item,添加,删除 RecyclerView使用(二)
  • 第三篇RecyclerView的监听方法RecyclerView使用(三)
  • 第四篇RecyclerView的拖动和滑动删除RecyclerView使用(四)

你可能感兴趣的:(RecyclerView使用(三))