Android RecyclerView自带原生点击和长按事件

RecyclerView 系统自带点击和长按事件(可复用)

 

  • 写在前面

我们用过RecyclerView的朋友都知道,它是不能直接设置其点击事件的,系统并没有给我们提供api,不像TextView,Button等控件,可以直接setOnClickListener(),所以退而求其次,利用曲线救国的策略,通过回调,我们一般都是在adapter里面,单独设置每一个控件的点击事件,然后回调出来,但是,这并不能复用,每次都得重新设计,所以,今天我们说一下,系统自带的可复用的RecyclerView的点击事件设置。​​​​​​

  • 关键类 

RecyclerView.OnItemTouchListener  (接口)

我们需要新建类,实现RecyclerView.OnItemTouchListener 这个接口,重写onInterceptTouchEvent(RecyclerView rv, MotionEvent e)方法,当我们通过事件传递,捕捉到手势事件之后,将它交给手势处理的方法,就能够实现单击及长按的事件监听。

    @Override
    public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) {
        View childView = rv.findChildViewUnder(e.getX(), e.getY());
        if (childView == null) {
            return false;
        }
        selectView = childView;
        selectPosition = rv.getChildAdapterPosition(childView);
        /**
         * 交给手势控制类来处理
         */
        return mGestureDetector.onTouchEvent(e);
    }

    @Override
    public void onTouchEvent(RecyclerView rv, MotionEvent e) {

    }

    @Override
    public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {

    }

 childView就是被点击的itemView,selectPosition就是被点击的position。

 

  • 设置监听 

设置回调监听,将GestureDetector方法(手势操作方法)的处理结果回调回去,就能够在我们的activity中得到对应的点击事件。

1. 定义监听接口

设置builder是为了方便只重写点击事件,或者只重写长按事件。  又定义一个normal接口是为了区别于其他的点击事件,这里并没有定义其他的点击事件。如果扩展,定义内部接口会比较好。

    public interface OnItemClickListener {

        interface Normal {

            void onItemClick(View view, int position);

            void onItemLongClick(View view, int position);

            class Builder implements Normal {

                @Override
                public void onItemClick(View view, int position) {

                }

                @Override
                public void onItemLongClick(View view, int position) {

                }
            }
        }


    }

 2. 添加监听构造方法

这是一个构造方法,将此方法作为一个实例,传入被调用的方法即可,调用方法见3.

    public RecyclerItemClickListener(Context context, final OnItemClickListener.Normal mListener) {

        mGestureDetector = new GestureDetector(context, new GestureDetector.SimpleOnGestureListener() {
            /**
             * 点击
             */
            @Override
            public boolean onSingleTapUp(MotionEvent e) {
                if (selectView != null && mListener != null){
                    mListener.onItemClick(selectView, selectPosition);
                    return true;
                }
                return super.onSingleTapUp(e);
            }

            /**
             * 长按
             */
            @Override
            public void onLongPress(MotionEvent e) {
                if (selectView != null && mListener != null){
                    mListener.onItemLongClick(selectView, selectPosition);
                }
            }

        });
    }

 

 3. 调用点击事件方法


    // recyclerView  调用自己的addOnItemTouchListener方法,参数传入我们定义的类RecyclerItemClickListener的实例
    recycleView.addOnItemTouchListener(new RecyclerItemClickListener(context, onItemClickListener));


    //  这是回调方法,在下面的回调里面添加自己的处理逻辑,这里有三种写法
    //  1.只回调单击事件
    private RecyclerItemClickListener.OnItemClickListener.Normal onItemClickListener = new RecyclerItemClickListener.OnItemClickListener.Normal.Builder() {
        @Override
        public void onItemClick(View view, int position) {

            // 在这里写自己的单击事件逻辑
        }
    };

    
    // 2.只回调长按事件
    private RecyclerItemClickListener.OnItemClickListener.Normal onItemClickListener = new RecyclerItemClickListener.OnItemClickListener.Normal.Builder() {
        @Override
        public void onItemLongClick(View view, int position) {

            // 在这里写自己的长按事件逻辑
        }
    };

    // 3.同时回调点击和长按事件
    private RecyclerItemClickListener.OnItemClickListener.Normal onItemClickListener = new RecyclerItemClickListener.OnItemClickListener.Normal() {
        @Override
        public void onItemClick(View view, int position) {

            // 在这里写自己的单击事件逻辑
        }

        @Override
        public void onItemLongClick(View view, int position) {

            // 在这里写自己的长按事件逻辑
        }
    };

 

  • 结束语

好了,可点击,可长按,可复用的RecyclerView的点击事件就介绍到这里了,欢迎大家指正批评。

 

附上完整代码



import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.View;

public class RecyclerItemClickListener implements RecyclerView.OnItemTouchListener {

    private GestureDetector mGestureDetector;

    /**
     * 被选择的view
     */
    private View selectView;
    /**
     * 被选择view的position
     */
    private int selectPosition;

    @Override
    public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) {
        View childView = rv.findChildViewUnder(e.getX(), e.getY());
        if (childView == null) {
            return false;
        }
        selectView = childView;
        selectPosition = rv.getChildAdapterPosition(childView);
        /**
         * 交给手势控制类来处理
         */
        return mGestureDetector.onTouchEvent(e);
    }

    @Override
    public void onTouchEvent(RecyclerView rv, MotionEvent e) {

    }

    @Override
    public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {

    }

   
    public RecyclerItemClickListener(Context context, final OnItemClickListener.Normal mListener) {

        mGestureDetector = new GestureDetector(context, new GestureDetector.SimpleOnGestureListener() {
            /**
             * 点击
             */
            @Override
            public boolean onSingleTapUp(MotionEvent e) {
                if (selectView != null && mListener != null){
                    mListener.onItemClick(selectView, selectPosition);
                    return true;
                }
                return super.onSingleTapUp(e);
            }

            /**
             * 长按
             */
            @Override
            public void onLongPress(MotionEvent e) {
                if (selectView != null && mListener != null){
                    mListener.onItemLongClick(selectView, selectPosition);
                }
            }

        });
    }

    public interface OnItemClickListener {

        interface Normal {

            void onItemClick(View view, int position);

            void onItemLongClick(View view, int position);

            class Builder implements Normal {

                @Override
                public void onItemClick(View view, int position) {

                }

                @Override
                public void onItemLongClick(View view, int position) {

                }
            }
        }


    }
}

 

 

 

 

 

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值