RecyclerView借助ItemTouchHelper实现拖动和滑动删除功能

RecyclerView是官方推荐代替ListView的空间,怎样实现RecyclerView列表元素的拖动呢?

官方提供了ItemTouchHelper类使用过程例如以下:


  • 定义ItemTouchHelper.Callback实现类,下面是几个重要的方法


package com.zms.copyapp.helper;

import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.helper.ItemTouchHelper;
import android.util.Log;

/**
 * Created by Msn on 2015/7/28.
 */
public class MyItemTouchHelperCallback extends ItemTouchHelper.Callback{

    private ItemTouchListener mItemTouchListener;

    public MyItemTouchHelperCallback(ItemTouchListener itemTouchListener){
        mItemTouchListener = itemTouchListener;
    }

    /**
     * 支持长按进入拖动
     * @return
     */
    @Override
    public boolean isLongPressDragEnabled() {
        return true;
    }

    @Override
    public boolean isItemViewSwipeEnabled() {
        return false;
    }

    /**
     * 指定拖动和滑动支持的方向
     * @param recyclerView
     * @param viewHolder
     * @return
     */
    @Override
    public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
    //List部分功能
//        int dragFlag = ItemTouchHelper.UP | ItemTouchHelper.DOWN;//拖动支持向下和向上
//        int swipeFlag = ItemTouchHelper.START | ItemTouchHelper.END;//滑动支持向左和向右
        //Grid部分功能
        int dragFlag = ItemTouchHelper.UP | ItemTouchHelper.DOWN |ItemTouchHelper.START | ItemTouchHelper.END;
        int swipeFlag = 0;
        return makeMovementFlags(dragFlag,swipeFlag);
    }

    @Override
    public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder source, RecyclerView.ViewHolder target) {
        Log.e("Test","onMove--------------------------------");
        mItemTouchListener.onItemMove(source.getAdapterPosition(), target.getAdapterPosition());
        return true;
    }

    @Override
    public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
        Log.e("Test", "onSwiped--------------------------------");
        mItemTouchListener.onItemDismiss(viewHolder.getAdapterPosition());
    }

    /**
     * 在每次View Holder的状态变成拖拽 (ACTION_STATE_DRAG) 或者 滑动 (ACTION_STATE_SWIPE)的时候被调用。
     * @param viewHolder
     * @param actionState
     */
    @Override
    public void onSelectedChanged(RecyclerView.ViewHolder viewHolder, int actionState) {
        if(actionState != ItemTouchHelper.ACTION_STATE_IDLE){
            ItemStatusListener listener = (ItemStatusListener)viewHolder;
            listener.onItemSelected();
        }
        super.onSelectedChanged(viewHolder, actionState);
    }

    /**
     * 在一个view被拖拽然后被放开的时候被调用,
     * @param recyclerView
     * @param viewHolder
     */
    @Override
    public void clearView(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
        super.clearView(recyclerView, viewHolder);
        ItemStatusListener listener = (ItemStatusListener)viewHolder;
        listener.onItemClear();
    }
}

  • 声明ItemTouchHelper。并绑定到待管理的RecyclerView上
 ItemTouchHelper.Callback helperCallback = new MyItemTouchHelperCallback(adapter);
        helper = new ItemTouchHelper(helperCallback);
        helper.attachToRecyclerView(recyclerView);


  • 在Adapter中定义滑动删除和拖动排序的数据逻辑
package com.zms.copyapp;

import android.graphics.Color;
import android.support.v4.view.MotionEventCompat;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;

import com.zms.copyapp.helper.ItemStatusListener;
import com.zms.copyapp.helper.ItemTouchListener;

import org.w3c.dom.Text;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * Created by Msn on 2015/7/28.
 */
public class MyRecyclerListAdapter extends RecyclerView.Adapter<MyRecyclerListAdapter.MyViewHolder>
            implements ItemTouchListener{
    public final static String[] STR_ARRAY = {"ONE","TWO","THREE","FOUR","FIVE","SIX","SEVEN","EIGTH","NINE","TEN"};
    private final List<String> mItems = new ArrayList<>();

    private OnDragListener dragListener;

    public MyRecyclerListAdapter(OnDragListener listener) {
        mItems.addAll((Arrays.asList(STR_ARRAY)));
        dragListener = listener;
    }

    @Override
    public void onItemMove(int fromPosition, int toPosition) {
        String prev = mItems.remove(fromPosition);
        mItems.add(toPosition > fromPosition ? toPosition - 1 : toPosition, prev);
        notifyItemMoved(fromPosition,toPosition);
    }

    @Override
    public void onItemDismiss(int position) {
        mItems.remove(position);
        notifyItemRemoved(position);
    }



    @Override
    public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_main,parent,false);
        return new MyViewHolder(view);
    }

    @Override
    public void onBindViewHolder(final MyViewHolder holder, int position) {
        holder.textView.setText(mItems.get(position));
        holder.handleImgv.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View view, MotionEvent motionEvent) {
                if(MotionEventCompat.getActionMasked(motionEvent)
                        == MotionEvent.ACTION_DOWN){
                    dragListener.onStartDrag(holder);
                    Log.e("Test","onTouch.ACTION_DOWN");
                }
                return false;
            }
        });
    }

    @Override
    public int getItemCount() {
        return mItems.size();
    }

    public  class MyViewHolder extends RecyclerView.ViewHolder implements ItemStatusListener{
        public ImageView handleImgv;
        public TextView textView;
        public MyViewHolder(View view){
            super(view);
            textView = (TextView)view.findViewById(R.id.text);
            handleImgv = (ImageView)view.findViewById(R.id.handle);
        }

        @Override
        public void onItemSelected() {
            itemView.setBackgroundColor(Color.LTGRAY);
        }

        @Override
        public void onItemClear() {
            itemView.setBackgroundColor(Color.TRANSPARENT);
        }
    }


    public interface OnDragListener{
        public void onStartDrag(MyViewHolder holder);
        public void onStartSwipe(MyViewHolder holder);
    }
}

这样一个拖动重排的功能就实现了:
RecyclerView借助ItemTouchHelper实现拖动和滑动删除功能