Since you started using RecyclerView instead of ListView, you’ll find a lot to learn. The previous learning records are as follows:
Today we will learn how to implement RecyclerView Item click events. There are three ways to implement an Item click event:
-
By RecyclerView existing method addOnItemTouchListener() to achieve
-
Add click listener when creating ItemView
-
When ItemView attach RecyclerView
1. ByRecyclerView
theaddOnItemTouchListener()
implementation
1.1 Viewing source Code
See RecyclerView source code can be seen,RecyclerView reserved an Item touch event method:
/**
* Add an {@link OnItemTouchListener} to intercept touch events before they are dispatched
* to child views or this view's standard scrolling behavior.
*
* Client code may use listeners to implement item manipulation behavior. Once a listener
* returns true from
* {@link OnItemTouchListener#onInterceptTouchEvent(RecyclerView, MotionEvent)} its
* {@link OnItemTouchListener#onTouchEvent(RecyclerView, MotionEvent)} method will be called
* for each incoming MotionEvent until the end of the gesture.
*
* @param listener Listener to add
* @see SimpleOnItemTouchListener
*/
public void addOnItemTouchListener(OnItemTouchListener listener) {
mOnItemTouchListeners.add(listener);
}
Copy the code
We can see from the comments that this method is called before the scrolling event. You need to pass in an OnItemTouchListener object. The OnItemTouchListener code looks like this:
public static interface OnItemTouchListener {
public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e);
public void onTouchEvent(RecyclerView rv, MotionEvent e);
public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept);
}
Copy the code
This interface also provides an implementation class, and the official is recommended to use the implementation class SimpleOnItemTouchListener
/**
* An implementation of {@link RecyclerView.OnItemTouchListener} that has empty method bodies and
* default return values.
*
<
p>
* You may prefer to extend this class if you don't need to override all methods. Another
* benefit of using this class is future compatibility. As the interface may change, we'll
* always provide a default implementation on this class so that your code won't break when
* you update to a new version of the support library.
*/
public static class SimpleOnItemTouchListener implements RecyclerView.OnItemTouchListener {
@Override
public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) {
return false;
}
@Override
public void onTouchEvent(RecyclerView rv, MotionEvent e) {
}
@Override
public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {
}
}
Copy the code
In the touch interface, a MotionEvent object is called back when touched, parsing the user’s actions using GestureDetectorCompat.
1.2 Implement click event monitoring
Write a ItemClickListener class inheritance SimpleOnItemTouchListener, construct the incoming RecyclerView object and click on the Item the callback, and overwrite the superclass Boolean OnInterceptTouchEvent (RecyclerView RV, MotionEvent E);
/** * Created by DevWiki on 2016/7/16. */ Public Class ItemClickListener extends RecyclerView.SimpleOnItemTouchListener { private OnItemClickListener clickListener; private GestureDetectorCompat gestureDetector; public interface OnItemClickListener { void onItemClick(View view, int position); void onItemLongClick(View view, int position); } public ItemClickListener(final RecyclerView recyclerView, OnItemClickListener listener) { this.clickListener = listener; gestureDetector = new GestureDetectorCompat(recyclerView.getContext(), new GestureDetector.SimpleOnGestureListener() { @Override public boolean onSingleTapUp(MotionEvent e) { View childView = recyclerView.findChildViewUnder(e.getX(), e.getY()); if (childView ! = null && clickListener ! = null && gestureDetector.onTouchEvent(e)) { clickListener.onItemClick(childView, recyclerView.getChildAdapterPosition(childView)); } return true; } @Override public void onLongPress(MotionEvent e) { View childView = recyclerView.findChildViewUnder(e.getX(), e.getY()); if (childView ! = null && clickListener ! = null) { clickListener.onItemLongClick(childView, recyclerView.getChildAdapterPosition(childView)); }}}); } @Override public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) { gestureDetector.onTouchEvent(e); return false; }}Copy the code
In the GestureDetectorCompat gesture callback we override:
-
Boolean onSingleTapUp(MotionEvent e) Click to lift the callback
-
Void onLongPress(MotionEvent E) Long press to call back
1.3 Using Event Listening
Add the addOnItemTouchListener() method to the RecyclerView object and then handle the events you need in the callback:
recyclerView.addOnItemTouchListener(new SingleItemClickListener(recyclerView, new SingleItemClickListener.OnItemClickListener() { @Override public void onItemClick(View view, int position) { DevLog.i("touch click name:" + position); Toast.makeText(SingleActivity.this, "touch click:" + position, Toast.LENGTH_SHORT).show(); } @Override public void onItemLongClick(View view, int position) { DevLog.i("touch long click:" + position); Toast.makeText(SingleActivity.this, "touch long click:" + position, Toast.LENGTH_SHORT).show(); }}));Copy the code
2. To createItemView
Add click listening when
This method, like the ListView method, adds a click event to the View created in the Adapter. Such as:
@Override public void bindCustomViewHolder(SingleHolder holder, final int position) { Person person = getItem(position); holder.nameView.setText(person.getName()); holder.ageView.setText(String.valueOf(person.getAge())); if (clickListener ! = null) { holder.nameView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { clickListener.onNameClick(position); }}); holder.ageView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { clickListener.onAgeClick(position); }}); }}Copy the code
Then add the listening callback to the Adapter object:
singleAdapter.setClickListener(new SingleAdapter.OnSingleItemClickListener() { @Override public void onNameClick(int position) { DevLog.i("adapter click name:" + position); Toast.makeText(SingleActivity.this, "adapter click name:" + position, Toast.LENGTH_SHORT).show(); } @Override public void onAgeClick(int position) { DevLog.i("adapter click age:" + position); Toast.makeText(SingleActivity.this, "adapter click name:" + position, Toast.LENGTH_SHORT).show(); }});Copy the code
3. WhenItemView
attach RecyclerView
When implementing
Get Your Clicks on RecyclerView Get Your clicks on RecyclerView Get Your clicks on RecyclerView
The code is as follows:
public class ItemClickSupport { private final RecyclerView mRecyclerView; private OnItemClickListener mOnItemClickListener; private OnItemLongClickListener mOnItemLongClickListener; private View.OnClickListener mOnClickListener = new View.OnClickListener() { @Override public void onClick(View v) { if (mOnItemClickListener ! = null) { RecyclerView.ViewHolder holder = mRecyclerView.getChildViewHolder(v); mOnItemClickListener.onItemClicked(mRecyclerView, holder.getAdapterPosition(), v); }}}; private View.OnLongClickListener mOnLongClickListener = new View.OnLongClickListener() { @Override public boolean onLongClick(View v) { if (mOnItemLongClickListener ! = null) { RecyclerView.ViewHolder holder = mRecyclerView.getChildViewHolder(v); return mOnItemLongClickListener.onItemLongClicked(mRecyclerView, holder.getAdapterPosition(), v); } return false; }}; private RecyclerView.OnChildAttachStateChangeListener mAttachListener = new RecyclerView.OnChildAttachStateChangeListener() { @Override public void onChildViewAttachedToWindow(View view) { if (mOnItemClickListener ! = null) { view.setOnClickListener(mOnClickListener); } if (mOnItemLongClickListener ! = null) { view.setOnLongClickListener(mOnLongClickListener); } } @Override public void onChildViewDetachedFromWindow(View view) {} }; private ItemClickSupport(RecyclerView recyclerView) { mRecyclerView = recyclerView; mRecyclerView.setTag(R.id.item_click_support, this); mRecyclerView.addOnChildAttachStateChangeListener(mAttachListener); } public static ItemClickSupport addTo(RecyclerView view) { ItemClickSupport support = (ItemClickSupport) view.getTag(R.id.item_click_support); if (support == null) { support = new ItemClickSupport(view); } return support; } public static ItemClickSupport removeFrom(RecyclerView view) { ItemClickSupport support = (ItemClickSupport) view.getTag(R.id.item_click_support); if (support ! = null) { support.detach(view); } return support; } public ItemClickSupport setOnItemClickListener(OnItemClickListener listener) { mOnItemClickListener = listener; return this; } public ItemClickSupport setOnItemLongClickListener(OnItemLongClickListener listener) { mOnItemLongClickListener = listener; return this; } private void detach(RecyclerView view) { view.removeOnChildAttachStateChangeListener(mAttachListener); view.setTag(R.id.item_click_support, null); } public interface OnItemClickListener { void onItemClicked(RecyclerView recyclerView, int position, View v); } public interface OnItemLongClickListener { boolean onItemLongClicked(RecyclerView recyclerView, int position, View v); }}Copy the code
The code above to set up a OnChildAttachStateChangeListener RecyclerView event listeners, when View the attach RecyclerView set up event listeners.
private RecyclerView.OnChildAttachStateChangeListener mAttachListener = new RecyclerView.OnChildAttachStateChangeListener() { @Override public void onChildViewAttachedToWindow(View view) { if (mOnItemClickListener ! = null) { view.setOnClickListener(mOnClickListener); } if (mOnItemLongClickListener ! = null) { view.setOnLongClickListener(mOnLongClickListener); } } @Override public void onChildViewDetachedFromWindow(View view) {} };Copy the code
4. Compare the three ways
The above three ways are:
-
By RecyclerView existing method addOnItemTouchListener() to achieve
-
Add click listener when creating ItemView
-
When ItemView attach RecyclerView
From the realization process of the above three ways, we can know:
-
All three can realize the monitoring of click events and long press events of ItemView.
-
The first method makes it easy to get the coordinates the user clicked.
-
The second and third methods are very convenient for listening on child Views in an ItemView.
-
The first method and the third method can be written in separate classes, making the code separate and cleaner than the second method written in Adapter
To sum up:
If all you want to do is listenItemView
Click event or long press event, three ways can be.
If you want to listen inItemView
Each child in theView
Click events, using the second or third comparison aspect.
5. Afterword.
The above three ways are learned in the RecyclerView process, the project address is as follows: dev-wiki /RecyclerView
If there is any error please correct, if you have a better way to achieve, please leave a message or contact me, thank you!
You can also follow my public account to get the latest articles: