记一次使用ItemTouchHelper实现RecyclerView列表上下拖动遇到的问题

本文记录了一次在使用ItemTouchHelper实现RecyclerView上下拖动功能时遇到的数据顺序不一致问题。通过详细分析代码和日志,发现originalPosition和targetPosition的差值不为1导致问题。解决方案是修改数据交换方式,避免直接使用Collections.swap(),以确保数据与显示一致。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

这是大概十多天前遇到的问题,只是一直懒得记录下来,现在补上。
是这样的,我需要实现一个列表并且要支持上下拖动,代码的实现跟网上大部分的实现类似,代码如下:

        ItemTouchHelper itemTouchHelper = new ItemTouchHelper(new ItemTouchHelper.Callback() {
            @Override
            public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
                // 支持上下拖动
                int dragFlags = ItemTouchHelper.DOWN | ItemTouchHelper.UP;
                // swipeFlags为0,即不支持滑动
                int swipeFlags = 0;
                return makeMovementFlags(dragFlags,swipeFlags);
            }

            @Override
            public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
                int originalPosition = viewHolder.getAdapterPosition();
                int targetPosition = target.getAdapterPosition();
                /***********************代码段一****************************/
                mAdapter.notifyItemMoved(originalPosition,targetPosition);
                Collections.swap(mList,originalPosition,targetPosition);
                /***********************代码段一 END********************/
                return true;
            }

            @Override
            public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {

            }
        });
		itemTouchHelper.attachToRecyclerView(recyclerView);

上面的代码,在我看来是没有任何问题的,直到在一次偶然的机会中,我发现mList里的数据的顺序和显示的数据的顺序不一致!我第一反应是这怎么可能? 只有在初始化和onMove里才会操作到mList,也没有涉及到子线程。既然出现了问题,那就要找原因。debug了十多次,无法复现,只能利用Logger,在代码段一的前后和在onSelectedChange里打印相关数据,在一顿操作后,复现了,显示的数据和最后打印出来的mList的数据的顺序不一致。然后就是从那一大串的log里找出原因了,终于在log中一处发现originalPosition和targetPosition的差值的绝对值不是1,是2,这就是数据不一致的原因。现有一个初始数据如下:

position显示的数据mList的数据
0AA
1BB
2CC

现假设originPosition为0,targetPosition为2。在mAdapter执行notifyItemMoved和对mList进行swap操作后,如下:

position显示的数据mList的数据
0BC
1CB
2AA

很明显,数据的顺序不一致。在后来的测试中发现,对item进行快速上下拖动时就会出现originalPosition与targetPosiion的差值的绝对值不为1的情况。

解决方案也非常简单, 将Collections.swap(mList,originalPosition,targetPosition);替换为以下代码即可:

String str = mList.remove(originalPosition);
mList.add(targetPosition,str);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值