Skip to content

侧滑删除,拖动排序

示例 - 侧滑删除,拖动排序

我们的目标:对于竖直的单项列表,左右滑动可删除选项,长按后拖动可改变选项位置。

侧滑删除 拖动排序

可以明确的是,我们需要监听到2种动作,左右侧滑和拖动。 为实现这个目标,我们可以使用官方提供的ItemTouchHelper

主要关注ItemTouchHelper.Callback类。ItemTouchHelper.Callback是一个抽象类,先来了解它的以下3个方法。

  • getMovementFlags 在此方法里面我们需要构建两个flag,一个是dragFlags,表示拖动效果支持的方向,另一个是swipeFlags,表示侧滑效果支持的方向。在我们的Demo中,拖动执行上下两个方向,侧滑执行左右两个方向,这些操作我们都可以在此方法里面定义。
  • onMove 当拖动事件已发生,会回调此方法。在此方法里面,我们通常会更新数据源。例如,一个ItemView从0拖到了1位置,那么对应的数据源也需要更改位置。
  • onSwiped 当侧滑事件已发生,会回调此方法。在此方法里面,我们也会更新数据源。与onMove方法不同到的是,我们在这个方法里面从数据源里面移除相应的数据,然后调用notifyXXX方法。

下面是ReViewTouchCallback类继承ItemTouchHelper.Callback

public class ReViewTouchCallback extends ItemTouchHelper.Callback {

    private final IActionListener mIActionListener;

    public ReViewTouchCallback(IActionListener IActionListener) {
        mIActionListener = IActionListener;
    }

    @Override
    public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
        int dragFlags = ItemTouchHelper.UP | ItemTouchHelper.DOWN; // 上下拖动
        int swipeFlags = ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT; // 向左滑动
        return makeMovementFlags(dragFlags, swipeFlags);
    }

    @Override
    public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
        return mIActionListener.onItemMove(viewHolder.getAdapterPosition(), target.getAdapterPosition());
    }

    @Override
    public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
        mIActionListener.onItemRemove(viewHolder.getAdapterPosition());
    }
}

IActionListener是监听器

public interface IActionListener {
    boolean onItemMove(int pos, int targetPos);

    void onItemRemove(int pos);
}

在activity中实际使用。监听到侧滑或者拖动事件时,对数据列表进行操作。

ItemTouchHelper itemTouchHelper = new ItemTouchHelper(new ReViewTouchCallback(new IActionListener() {
    @Override
    public boolean onItemMove(int src, int target) {
        Collections.swap(mAdapter.getDataList(), src, target);
        mAdapter.notifyItemMoved(src, target);
        return true;
    }

    @Override
    public void onItemRemove(int pos) {
        mAdapter.getDataList().remove(pos);
        mAdapter.notifyItemRemoved(pos);
    }
}));
itemTouchHelper.attachToRecyclerView(binding.reView);

移动item,需要调用notifyItemMoved方法。删除item时,调用notifyItemRemoved方法。