
Summary
This paper mainly introduces the Item click of RecyclerView in android, the response of long press events and the encapsulation of the sliding loading function. Previous articles introduced RecyclerView.Adapter from the perspective of RecyclerView.Adapter encapsulation and Functional Extension Then with Recycler View and Swipe RefreshLayout Up-slip Loading and Down-pull Refreshing Operation. from Up-slip Loading and Down-pull Refreshing In this article, you can see two inconveniences when using RecyclerView directly:
- RecyclerView does not provide Item clicks and long press events, which need to be implemented by itself.
- If RecyclerView is used more frequently in software, there are more scenarios that need to be loaded up. If it is not encapsulated, then every time it is loaded up, a large amount of OnScrollListener duplicate code will be written, which will affect code reading. As for drop-down refresh, it is based on Swipe Refresh Layout and does not need to be encapsulated in RecyclerView.
Item response click, long press event
There are two ways to realize the Item response click and long press events of RecyclerView:
- Starting from RecyclerView itself, with the help of GestureDetector class, Item clicks and long press events to respond.
- From the last article Encapsulation of RecyclerView.Adapter Starting from BaseAdapter, with the help of BaseAdapter, Item internal controls can be added the ability of event monitoring, and Item root office can be added an event monitoring, so as to enable Item to respond to click and press events for a long time.
Implementing Click and Long Press Event Monitoring with Gesture Detector Class
Referring to the usage of setOnClickListener() of ListView, when you want to make the Item of RecyclerView able to listen for clicks and long press events, you need to implement a listening interface and pass it in to RecyclerView. The encapsulated usage should be as follows:
//Click Events baseRecyclerView.setOnItemClickListener(new BaseRecyclerView.OnItemClickListener() { @Override public void onItemClick(View view, BaseHolder baseHolder, int position) { //When you call back, you can return the view, holder and location of the Item you clicked on. } }); //Event of long press recyclerView.setOnItemLongClickListener(new BaseRecyclerView.OnItemLongClickListener(){ @Override public void onItemLongClick(View view, BaseHolder baseHolder, int position) { //When you call back, you can return the view, holder and location of the Item you clicked on. } });
So in the BaseRecyclerView class, you should have:
- Definition of OnItemClickListener interface containing onItemClick() method;
- The definition of OnItemClickLOngListener interface containing onItemLongClick() method;
- Reference variable of OnItemClickListener interface type (used to receive incoming OnItemClickListener);
- Reference variable of OnItemClickLongListener interface type (used to receive incoming OnItemClickLongListener);
- Can identify the user clicks, long clicks and callbacks of the object,
- setOnItemClickListener Method
- setOnItemLongClickListener method.
The code is shown below.
public class BaseRecyclerView extends RecyclerView { //Reference Variables of OnItemClickListener Interface Type private OnItemClickListener onItemClickListener; //Reference variable of OnItemClickLongListener interface type private OnItemLongClickListener onItemLongClickListener; //Can identify the user clicks, long clicks can be called back to the object private GestureDetectorCompat gestureDetectorCompat; //Constructive function of overload public BaseRecyclerView(Context context) { super(context); //Get an instance of Gesture Detector Compat this.gestureDetectorCompat = getGestureDetectorCompat(); } public BaseRecyclerView(Context context, @Nullable AttributeSet attrs) { super(context, attrs); this.gestureDetectorCompat = getGestureDetectorCompat(); } public BaseRecyclerView(Context context, @Nullable AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); this.gestureDetectorCompat = getGestureDetectorCompat(); } //Assignment listener public void setOnItemClickListener(OnItemClickListener onItemClickListener){ this.onItemClickListener = onItemClickListener; } public void setOnItemLongClickListener(OnItemLongClickListener onItemLongClickListener){ this.onItemLongClickListener = onItemLongClickListener; } //Interface definition public interface OnItemClickListener{ void onItemClick(View view, BaseHolder baseHolder, int position); } public interface OnItemLongClickListener{ void onItemLongClick(View view, BaseHolder baseHolder, int position); } @Override public boolean onInterceptTouchEvent(MotionEvent e) { gestureDetectorCompat.onTouchEvent(e); return false; } //Get an instance of Gesture Detector Compat public GestureDetectorCompat getGestureDetectorCompat(){ return new GestureDetectorCompat(getContext(), new GestureDetector.SimpleOnGestureListener(){ @Override public boolean onSingleTapUp(MotionEvent e) { //Judge click events View childView = findChildViewUnder(e.getX(), e.getY()); if (childView != null && onItemClickListener !=null){ //Callback click event onItemClickListener.onItemClick(childView, (BaseHolder)getChildViewHolder(childView), getChildAdapterPosition(childView)); } return true; } @Override public void onLongPress(MotionEvent e) { //Judged as a long-term event View childView = findChildViewUnder(e.getX(), e.getY()); if (childView != null && onItemLongClickListener !=null){ //Callback by Event onItemLongClickListener.onItemLongClick(childView, (BaseHolder)getChildViewHolder(childView), getChildAdapterPosition(childView)); } } }); } }
Implementing Click and Long Press Event Monitoring with BaseAdapter
This method is relatively simple, adding a setOnClickListener() method to the BaseAdapter to hold a reference to View.OnClickListener, and then binding the listener to Ite through the setOnClickListener(int viewId, View.OnClickListener listener) method of the BaseHolder parameter in the onBind() method of BaseAdapter. M is on the root part of Item (an id needs to be assigned to the root part of Item).
BaseAdapter improvements:
//Add a View.OnClickListener variable View.OnClickListener onClickListener; //Add a setOnClickListener() public void setOnClickListener(View.OnClickListener onClickListener){ this.onClickListener = onClickListener; }
Subclass Adapter needs to pay attention to passing onClickListener to holder
@Override public void onBind(BaseHolder holder, final Contact contact, int position) { holder.setOnClickListener(R.id.item, onClickListener); }
Usage method:
adapter.setOnClickListener(new View.OnClickListener(){ @Override public void onClick(View v) { //Click event callback } });
Encapsulate the response to the sliding load event
Improvement based on the BaseRecyclerView code above
//Define an OnLoadableListener listening interface public interface OnLoadableListener{ void load(); } //Add an OnLoadableListener reference variable private OnLoadableListener onLoadableListener; //Adding a setter Method for Assigning OnLoadableListener public void setOnLoadableListener(OnLoadableListener onLoadableListener){ this.onLoadableListener = onLoadableListener; } //Add a function that binds the received OnLoadableListener to the current BaseRecyclerView public void addOnLoadableListener(OnLoadableListener onLoadableListener){ addOnScrollListener(new RecyclerView.OnScrollListener() { @Override public void onScrolled(RecyclerView recyclerView, int dx, int dy) { super.onScrolled(recyclerView, dx, dy); //The encapsulated BaseAdapter adapter used if (((LinearLayoutManager)getLayoutManager()). findLastVisibleItemPosition() == getAdapter().getItemCount()-1){ //Perform load callback operation onLoadableListener.load(); } } }); }
Usage method
recyclerView.setOnLoadableListener(new BaseRecyclerView.OnLoadableListener() { @Override public void load() { if (!isLoading) { isLoading = true; //Loading operation //...... isLoading = false; } } });