RecyclerView 使用ItemTouchHelper类实现拖拽排序

记得以前还没有RecyclerView的时候,做拖拽排序很麻烦,而现在因为RecyclerView的诞生,很多复杂的操作都可以完美实现了,例如轮播、流式布局等等。

先写一个简单的RecyclerView例子,然后慢慢拓展吧。

public class MoveItemActivity extends AppCompatActivity {
    private RecyclerView rl;
    private MyAdapter adapter;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_coo4);
        initRecycler();
    }

    private void initRecycler() {
        rl = findViewById(R.id.rv_content);
        rl.setLayoutManager(new LinearLayoutManager(this));
        List<String> list = new ArrayList<>();
        for (int i = 0; i < 50; i++) {
            list.add("这是模拟数据" + i);
        }
        rl.setAdapter(adapter = new MyAdapter(list));
    }


    public class MyAdapter extends RecyclerView.Adapter<Holder> implements ItemTouchMoveListener {
        List<String> list;


        public MyAdapter(List<String> list) {
            this.list = list;
        }

        @NonNull
        @Override
        public Holder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
            View inflate = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_recycler_main, parent, false);
            Holder holder = new Holder(inflate);
            holder.name = inflate.findViewById(R.id.tv_name);
            holder.image = inflate.findViewById(R.id.iv_image);
            return holder;
        }

        @Override
        public void onBindViewHolder(@NonNull Holder holder, int position) {
            holder.name.setText(list.get(position));
        }

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


    class Holder extends RecyclerView.ViewHolder {
        public TextView name;
        public View image;

        public Holder(@NonNull View itemView) {
            super(itemView);
        }
    }
}

运行截图:

运行截图

使用v7包提供的ItemTouchHelper类处理Item的拖拽事件:

  • 1.默认构造:
    /**
     * Creates an ItemTouchHelper that will work with the given Callback.
     * <p>
     * You can attach ItemTouchHelper to a RecyclerView via
     * {@link #attachToRecyclerView(RecyclerView)}. Upon attaching, it will add an item decoration,
     * an onItemTouchListener and a Child attach / detach listener to the RecyclerView.
     *
     * @param callback The Callback which controls the behavior of this touch helper.
     */
    public ItemTouchHelper(Callback callback) {
        mCallback = callback;
    }
  • 2.可以看到构造需要一个Callback,所以我们写个类进行实现:
public class ItemTouchCallback extends ItemTouchHelper.Callback {


    /**
     * 判断动作方向
     */
    @Override
    public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
        int dragFlags = ItemTouchHelper.UP | ItemTouchHelper.DOWN;
        int swipeFlags = ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT;
        int flags = makeMovementFlags(dragFlags, swipeFlags);
        return flags;
    }

    /**
     * 拖拽回调
     */
    @Override
    public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
        if (viewHolder.getItemViewType() != target.getItemViewType()) {
            return false;
        }
        return true;
    }

    /**
     * 侧滑回调
     */
    @Override
    public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {

    }

    /**
     * 长按拖拽开关 
     *
     * @return 代表是否开启长按拖拽
     */
    @Override
    public boolean isLongPressDragEnabled() {
        return true;
    }
}
  • 3.将监听与RecyclerView进行绑定:
new ItemTouchHelper(new ItemTouchCallback()).attachToRecyclerView(rl); 
  • 4.此时RecyclerView已经可以拖动排序了,但是这里还有一个坑,UI因为拖动改变了顺序,而我们真实的数据还是原来的顺序,所以我们还需要在onMove方法中写一个监听,或者将adapter的数据传到ItemTouchCallback类,进行位置交换操作,例如:
    /**
     * 拖拽回调
     */
    @Override
    public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
        if (viewHolder.getItemViewType() != target.getItemViewType()) {
            return false;
        }
        //将我们的真实(List)数据位置交换
        moveListener.onItemMove(viewHolder.getAdapterPosition(), target.getAdapterPosition());
        return true;
    }

gif预览:

gif预览

猜你喜欢

转载自blog.csdn.net/c__chao/article/details/80612668