[[185238]] Preface Starting from Android 5.0, Google launched a new control RecyclerView. Compared with the earlier ListView, it has many advantages and powerful functions. It also provides great convenience for our developers. Today, I will learn how to easily achieve the effects of sliding deletion and dragging with RecyclerView, as shown in the figure below. I believe that students who have studied RecyclerView should know very well how to achieve such an effect. If using ListView, such an effect may be a bit troublesome to achieve, but in front of the powerful RecyclerView, such an effect only requires very little code, because Google provides us with a powerful tool class ItemTouchHelper, which has handled the implementation of RecyclerView dragging and sliding, and we can implement our own animations in it, as well as customize the effects we want. ItemTouchHelper.Callback has several important abstract methods. We inherit this abstract class and override the abstract methods. It is an important callback for us to implement sliding and dragging. - int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder)
This method returns an integer that specifies the direction in which dragging and sliding are allowed. Use makeMovementFlags(int dragFlags, int swipeFlags) to return. The first parameter of this method is used to specify dragging, and the second parameter is used to specify sliding. There are 6 direction parameters - ItemTouchHelper.UP //Slide and drag upward
-
- ItemTouchHelper.DOWN //Down
-
- ItemTouchHelper.LEFT // Left
-
- ItemTouchHelper.RIGHT // right
-
- ItemTouchHelper.START // Depends on the horizontal start direction of the layout direction
-
- ItemTouchHelper.END //Horizontal end direction dependent on layout direction
- boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target)
The onMove method is the callback of dragging. The parameter viewHolder is the dragged Item, and target is the Item at the target position of the drag. If this method returns true, it means the position has been switched, otherwise it returns false. - void onSwiped(RecyclerView.ViewHolder viewHolder, int direction)
The onSwiped method is the Item sliding callback, viewHolder is the sliding item, and direction is the sliding direction. The above three methods are the methods that must be rewritten, of course there are some other optional methods. - /**
-
- * Whether the item supports long press and drag
-
- *
-
- * @return
-
- * true to support long press operation
-
- * false does not support long press operation
-
- */
-
- oolean isLongPressDragEnabled()
-
-
-
- /**
-
- * Whether the item supports sliding
-
- *
-
- * @return
-
- * true supports sliding operation
-
- * false does not support sliding operation
-
- */
-
- oolean isItemViewSwipeEnabled()
-
-
-
- /**
-
- * Draw Item during movement
-
- *
-
- * @param c
-
- * @param recyclerView
-
- * @param viewHolder
-
- * @param dX
-
- * X-axis moving distance
-
- * @param dY
-
- * Y axis movement distance
-
- * @param actionState
-
- * The current item status
-
- * @param isCurrentlyActive
-
- * If the current user operation is true , otherwise it is false
-
- */
-
- nChildDraw(Canvas c, RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, float dX, float dY, int actionState, boolean isCurrentlyActive)
It should be noted that if we want to implement dragging or sliding, we must return true to the method above to determine whether dragging or sliding is supported, otherwise the onMove or onSwiped method will not be executed. Functionality - adapter=new CustomAdapter(getActivity(),strings);
-
- recycleview.setAdapter(adapter);
-
- ItemTouchHelper.Callback callback=new RecycleItemTouchHelper(adapter);
-
- ItemTouchHelper itemTouchHelper=new ItemTouchHelper(callback);
-
- itemTouchHelper.attachToRecyclerView(recycleview);
The ItemTouchHelper construction method receives an ItemTouchHelper.Callback parameter, and this Callback is the tool class we mentioned above. After initializing ItemTouchHelper, we associate our implemented ItemTouchHelper.Callback with RecyclerView through its attachToRecyclerView(@Nullable RecyclerView recyclerView) method to achieve our desired effect. The code looks very simple, right? Next, let's take a look at our custom Callback. - package com.example.xh.adapter;
-
-
-
- import android.content.res.Resources;
-
- import android.graphics.Bitmap;
-
- import android.graphics.BitmapFactory;
-
- import android.graphics.Canvas;
-
- import android.graphics.Paint;
-
- import android.graphics.Rect;
-
- import android.support.v7.widget.RecyclerView;
-
- import android.support.v7.widget.helper.ItemTouchHelper;
-
- import android.util.Log;
-
- import android. view . View ;
-
-
-
- import com.example.xh.R;
-
- import com.example.xh.utils.MyApplication;
-
-
-
- /**
-
- * Created by xiehui on 2017/2/23.
-
- */
-
- public class RecycleItemTouchHelper extends ItemTouchHelper.Callback{
-
- private static final String TAG = "RecycleItemTouchHelper" ;
-
- private final ItemTouchHelperCallback helperCallback;
-
-
-
- public RecycleItemTouchHelper(ItemTouchHelperCallback helperCallback) {
-
- this.helperCallback = helperCallback;
-
- }
-
-
-
- /**
-
- * Set the slide type flag
-
- *
-
- * @param recyclerView
-
- * @param viewHolder
-
- * @return
-
- * Returns an integer type flag to determine whether the item's movement behavior is allowed
-
- */
-
- @Override
-
- public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
-
- Log.e(TAG, "getMovementFlags: " );
-
- //START right to leftEND left to rightLEFT leftRIGHT right UP up
-
- //If a value is passed as 0, it means that the operation is not triggered. The number of settings supports dragging up and down, and supports sliding to the right
-
- return makeMovementFlags(ItemTouchHelper.UP|ItemTouchHelper.DOWN,ItemTouchHelper. END );
-
- }
-
- /**
-
- * Whether the item supports long press and drag
-
- *
-
- * @return
-
- * true to support long press operation
-
- * false does not support long press operation
-
- */
-
- @Override
-
- public boolean isLongPressDragEnabled() {
-
- return super.isLongPressDragEnabled();
-
- }
-
- /**
-
- * Whether the item supports sliding
-
- *
-
- * @return
-
- * true supports sliding operation
-
- * false does not support sliding operation
-
- */
-
- @Override
-
- public boolean isItemViewSwipeEnabled() {
-
- return super.isItemViewSwipeEnabled();
-
- }
-
- /**
-
- * Drag and switch Item callback
-
- *
-
- * @param recyclerView
-
- * @param viewHolder
-
- * @param target
-
- * @return
-
- * If the item changes position, return true ; otherwise, return false
-
- */
-
- @Override
-
- public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
-
- Log.e(TAG, "onMove: " );
-
- helperCallback.onMove(viewHolder.getAdapterPosition(),target.getAdapterPosition());
-
- return true ;
-
- }
-
- /**
-
- * Slide Item
-
- *
-
- * @param viewHolder
-
- * @param direction
-
- * The direction in which the item slides
-
- */
-
- @Override
-
- public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
-
- Log.e(TAG, "onSwiped: " );
-
- helperCallback.onItemDelete(viewHolder.getAdapterPosition());
-
- }
-
- /**
-
- * Callback when Item is selected
-
- *
-
- * @param viewHolder
-
- * @param actionState
-
- * The current item status
-
- * ItemTouchHelper.ACTION_STATE_IDLE idle state
-
- * ItemTouchHelper.ACTION_STATE_SWIPE Sliding state
-
- * ItemTouchHelper#ACTION_STATE_DRAG dragging state
-
- */
-
- @Override
-
- public void onSelectedChanged(RecyclerView.ViewHolder viewHolder, int actionState) {
-
- super.onSelectedChanged(viewHolder, actionState);
-
- }
-
- public interface ItemTouchHelperCallback{
-
- void onItemDelete( int positon);
-
- void onMove( int fromPosition, int toPosition);
-
- }
-
- }
By default, dragging and sliding are supported, that is, isLongPressDragEnabled() and isItemViewSwipeEnabled() return true. In this class, we create an interface ItemTouchHelperCallback and create two abstract methods, representing dragging and sliding respectively. In the onMove method, we call back to create the interface method interface onMove(int fromPosition, int toPosition) we created, and pass in the drag and Item's posion and target posion. The posion is obtained through ViewHolder's getAdapterPosition(), and then the onItemDelete(int position) is called back in the sliding callback method onSwiped. At this point, our custom ItemTouchHelper.Callback is created. After completing the above, we only need to implement the RecycleItemTouchHelper.ItemTouchHelperCallback interface in our custom Adapter, and then update the interface in the callback method, as shown in the callback method implementation in Apdater below. - @Override
-
- public void onItemDelete( int positon) {
-
- list.remove(positon);
-
- notifyItemRemoved(positon);
-
- }
-
-
-
- @Override
-
- public void onMove( int fromPosition, int toPosition) {
-
- Collections.swap(list,fromPosition,toPosition);//Exchange data
-
- notifyItemMoved(fromPosition,toPosition);
-
- }
We delete the corresponding posion data in the onItemDelete method, exchange the corresponding item data through the Collections.swap method in the onMove method, and then call notifyItemRemoved and notifyItemMoved respectively to update the UI through the adapter. Well, the function has been implemented here. Did you find that there are very few codes? Of course, it is just more verbose. Functional upgrade Through the implementation of the simple code above, you can already slide to delete and drag. Of course, you may find that there is no animation and no background when sliding to delete. But I want to change the background and a delete icon will appear during the sliding process to give users feedback and let them know that the operation is to delete data. Of course, you will also want to add an animation during the deletion process. In fact, it is not very troublesome to achieve this effect. Next, a new method will be implemented. Oh, no, it was mentioned before. - onChildDraw(Canvas c, RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, fl
This method is the callback for drawing the Item during the movement process. When actionState==ItemTouchHelper.ACTION_STATE_SWIPE, we draw the background and delete the image when sliding. initialization - /**
-
- * Draw Item during movement
-
- *
-
- * @param c
-
- * @param recyclerView
-
- * @param viewHolder
-
- * @param dX
-
- * X-axis moving distance
-
- * @param dY
-
- * Y axis movement distance
-
- * @param actionState
-
- * The current item status
-
- * @param isCurrentlyActive
-
- * If the current user operation is true , otherwise it is false
-
- */
-
- @Override
-
- public void onChildDraw(Canvas c, RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, float dX, float dY, int actionState, boolean isCurrentlyActive) {
-
- //Implement the background and pictures by yourself when sliding
-
- if (actionState==ItemTouchHelper.ACTION_STATE_SWIPE){
-
-
-
- //When dX is greater than 0, slide to the right, and when dX is less than 0, slide to the left
-
- View itemView=viewHolder.itemView; //Get the sliding view
-
- Resources resources= MyApplication.getAppContext().getResources();
-
- Bitmap bitmap = BitmapFactory.decodeResource(resources, R.drawable. delete ); //Get the background image of the deletion instruction
-
- int padding =10; //padding for drawing the image
-
- int maxDrawWidth=2*padding+bitmap.getWidth(); //*** drawing width
-
- Paint paint=new Paint();
-
- paint.setColor(resources.getColor(R.color.btninvalid));
-
- int x=Math.round(Math. abs (dX));
-
- int drawWidth = Math.min ( x, maxDrawWidth); //Actual drawing width, take the minimum value of real-time sliding distance x and maximum drawing distance maxDrawWidth
-
- int itemTop=itemView.getBottom()-itemView.getHeight(); //Draw the top position
-
- //Slide to the right
-
- if(dX>0){
-
- //Draw a background in real time based on sliding
-
- c.drawRect(itemView.getLeft(),itemTop,drawWidth,itemView.getBottom(),paint);
-
- // Draw the image on the background
-
- if (x>padding){//Start drawing the image when the sliding distance is greater than padding
-
- //Specify the location where the picture is drawn
-
- Rect rect=new Rect(); //Drawing location
-
- rect.left =itemView.getLeft()+padding;
-
- rect.top =itemTop+(itemView.getBottom()-itemTop-bitmap.getHeight())/2;//Center the image
-
- int maxRight=rect.left + bitmap.getWidth();
-
- rect. right =Math. min (x,maxRight);
-
- rect.bottom= rect.top +bitmap.getHeight();
-
- //Specify the drawing area of the image
-
- Rect rect1= null ;
-
- if (x
After the above processing, we can see our customized blue and low deletion background by sliding. At this time, we may still have doubts whether this deletion is very abrupt. Then add a transparency animation to it, as shown below. - float alpha = 1.0f - Math. abs (dX) / ( float ) itemView.getWidth();
-
- itemView.setAlpha(alpha);
Well, here we have introduced the sliding deletion and dragging functions of RecyclerView. If you have any questions, please leave a message. Have a wonderful day. Source code portal - https://github.com/xiehui999/fuseProgram
|