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

xiaoxiao2025-05-13  42

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) { } } } } }

 

 

 

 

 

转载请注明原文地址: https://www.6miu.com/read-5030061.html

最新回复(0)