返回

RecyclerView 长按删除无法正常工作?一个修复指南

Android

## RecyclerView 长按删除元素修复指南

### 问题:长按不拖动无法正确移除元素

当你使用 RecyclerView 实现元素的长按删除功能时,可能会遇到这样一个问题:当你长按一个元素但没有将其拖到新位置时,该元素虽然从列表中消失了,但仍然可见。

### 原因:ItemTouchHelper 拦截了触摸事件

导致这个问题的原因是,当你添加 ItemTouchHelper 来拖放项目时,它会重写 RecyclerView 的 onInterceptTouchEvent 方法。这个方法决定了是否拦截触摸事件。当长按一个项目时,ItemTouchHelper 会拦截触摸事件并开始拖放过程。

然而,当你不拖动项目而是释放时,ItemTouchHelper 会取消拖放过程,但它不会释放对触摸事件的拦截。因此,当单击该项目时,不会触发 RecyclerView 的 onTouchEvent 方法。

### 解决方案:释放触摸事件拦截

为了解决这个问题,我们需要覆盖 ItemTouchHelper 的 onChildViewReleased 方法。这个方法在拖放过程取消时调用。在该方法中,我们可以释放对触摸事件的拦截。

@Override
public void onChildViewReleased(@NonNull ViewHolder viewHolder, int swipeDir) {
    super.onChildViewReleased(viewHolder, swipeDir);
    actionState = ItemTouchHelper.ACTION_STATE_IDLE;
}

### 代码示例

将上述代码添加到提供的 MainActivity 代码中:

class MainActivity extends AppCompatActivity {
    // ...

    private ItemTouchHelper myItemTouchHelper = new ItemTouchHelper(new ItemTouchHelper.SimpleCallback(ItemTouchHelper.UP | ItemTouchHelper.DOWN, 0) {
        // ...

        @Override
        public void onChildViewReleased(@NonNull ViewHolder viewHolder, int swipeDir) {
            super.onChildViewReleased(viewHolder, swipeDir);
            actionState = ItemTouchHelper.ACTION_STATE_IDLE;
        }
    });

    // ...
}

### 结论

通过这些更改,长按项目而不将其拖动到新位置时,该项目将被正确移除,并且不会在列表中可见。

### 常见问题解答

1. 为什么我需要覆盖 onChildViewReleased 方法?

为了释放 ItemTouchHelper 对触摸事件的拦截。

2. ItemTouchHelper 的 actionState 是什么?

它表示 ItemTouchHelper 的当前状态,例如 ACTION_STATE_IDLE 或 ACTION_STATE_SWIPE。

3. 为什么设置 actionState = ItemTouchHelper.ACTION_STATE_IDLE?

这将使 ItemTouchHelper 停止拦截触摸事件。

4. 我还需要做其他事情吗?

不一定,但建议检查你的代码是否有任何其他可能干扰触摸事件处理的地方。

5. 如果我仍然遇到问题怎么办?

仔细检查你的代码,确保正确实现了所有步骤。如果你仍然遇到问题,请查看 RecyclerView 和 ItemTouchHelper 的文档以获取更多信息。