You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android RecyclerView通过ItemTouchHelper拖拽重排后item位置未更新问题

问题根因

你遇到的拖拽后位置显示不更新的问题,核心有两个错误点:

  • onMove方法返回值错误:你当前返回false,ItemTouchHelper会判定本次移动操作未被处理,不会完成后续的位置同步流程。
  • 仅调用notifyItemMoved只会触发移动动画,不会刷新受影响区间内item的绑定数据:你按钮上显示的位置是bindViewHolder时赋值的旧值,移动后没有重新绑定所以显示不变。

解决方案

  1. 修正onMove返回值为true
  2. 移动后刷新受影响的item区间,让所有位置变动的item重新绑定数据,显示最新位置
  3. 要获取item最新位置时,在onBindViewHolder中使用传入的position参数,或者任意场景下调用ViewHolder.getAdapterPosition()方法即可拿到实时位置。

修改后代码示例

ItemTouchHelper.SimpleCallback simpleCallback = new ItemTouchHelper.SimpleCallback(ItemTouchHelper.UP
                | ItemTouchHelper.DOWN | ItemTouchHelper.START | ItemTouchHelper.END , 0) {
            @Override
            public boolean onMove(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder, @NonNull RecyclerView.ViewHolder target) {
                int fromPosition = viewHolder.getAdapterPosition();
                int toPosition = target.getAdapterPosition();
                // 交换数据源
                Collections.swap(datalist,fromPosition,toPosition);
                // 通知item移动
                recyclerView.getAdapter().notifyItemMoved(fromPosition,toPosition);
                // 刷新受影响的区间,更新item上显示的位置信息
                int min = Math.min(fromPosition, toPosition);
                int max = Math.max(fromPosition, toPosition);
                recyclerView.getAdapter().notifyItemRangeChanged(min, max - min + 1);
                // 处理了移动事件返回true
                return true;
            }

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

            }

            // 可选:如果需要在拖拽结束时获取最终位置,重写这个方法
            @Override
            public void onSelectedChanged(@Nullable RecyclerView.ViewHolder viewHolder, int actionState) {
                super.onSelectedChanged(viewHolder, actionState);
                if (actionState == ItemTouchHelper.ACTION_STATE_IDLE && viewHolder != null) {
                    // 此时获取的就是拖拽结束后item的最终位置
                    int finalPosition = viewHolder.getAdapterPosition();
                }
            }
        };

Adapter绑定逻辑示例

在onBindViewHolder中直接使用方法传入的position参数即可获取最新位置:

@Override
public void onBindViewHolder(@NonNull MyViewHolder holder, int position) {
    // 直接用这个position就是最新位置
    holder.button.setText("按钮" + position);
    // 也可以把位置存到按钮的tag里,后续点击时直接取
    holder.button.setTag(position);
}

内容的提问来源于stack exchange,提问作者Priyanshu Pundhir

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.25 20:24:04