RecyclerView高级使用(二)-垂直拖拽排序的简单实现

先看看要实现的效果图:
![简单的垂直拖拽排序](https://img-blog.csdnimg.cn/20210329142737702.gif#pic_center
效果比较简单,就是一个垂直列表,然后可以拖动其子条目进行排序。
因此采用的方式还是RecyclerView+ItemTouchHelper,关于ItemTouchHelper的相关说明及使用还可以参考RecyclerView高级使用(一)-侧滑删除的简单实现RecyclerView细节研究-RecyclerView点击错位问题的探讨与修复。这里我们需要自己手写一个类VerticalDragSortHelperCallBack去继承ItemTouchHelper.Callback,我们需要实现下面的方法:

	@Override
    public int getMovementFlags(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder) {
        int dragFlag = ItemTouchHelper.UP | ItemTouchHelper.DOWN;
        return makeMovementFlags(dragFlag, ItemTouchHelper.ACTION_STATE_IDLE);
    }

    @Override
    public boolean onMove(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder, @NonNull RecyclerView.ViewHolder target) {
        int fromPos = viewHolder.getAdapterPosition();
        int toPos = target.getAdapterPosition();
        Log.d("onMove", fromPos + "--->" + toPos);
        //1、从数据源上交换条目的位置
        Collections.swap(recyclerItemList, fromPos, toPos);
        //2、从视图上通知刷新视图的改变
        recyclerView.getAdapter().notifyItemMoved(fromPos, toPos);

        //3、更正实际点击的position,防止点击时,position错乱
        int startPos = Math.min(fromPos, toPos);
        int itemCount = Math.abs(fromPos - toPos) + 1;
        recyclerView.getAdapter().notifyItemRangeChanged(startPos, itemCount);

        //4、PS:2和3的合体步骤可以用4替代,但是就没有了替换动画了,而且刷新效率比上面低,是全局刷新
//        recyclerView.getAdapter().notifyDataSetChanged();

        //请注意该返回值:只有在返回true的时候,才会走onMoved方法
        return true;
    }

    @Override
    public void onMoved(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder, int fromPos, @NonNull RecyclerView.ViewHolder target, int toPos, int x, int y) {
        super.onMoved(recyclerView, viewHolder, fromPos, target, toPos, x, y);
        Log.d("onMoved", "第一个:" + recyclerItemList.get(0).toString() + " " + fromPos + "--->" + toPos);
        Log.d("onMoved", "第二个:" + recyclerItemList.get(1).toString() + " " + fromPos + "--->" + toPos);
        if (onDragListener != null) {
            onDragListener.onItemMoved(viewHolder, target, fromPos, toPos);
        }
    }

    @Override
    public boolean isLongPressDragEnabled() {
        return true;
    }

需要注意的是:
1、因为垂直方向拖拽,所以getMovemonetFlags返回的是DOWNUP
2、在onMove中,pos由于是从零开始计算的,所以实际的刷新条目个数要+1
3、在onMove中,关于数据的交换,采用了系统Collections的swap交换,更为高效
4、isLongPressDragEnabled表示是否是长按后才启用拖拽,这里需要返回true,表示需要

源码下载地址:github

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值