【问题标题】:Android - Swipe to delete RecyclerViewAndroid - 滑动删除 RecyclerView
【发布时间】:2023-03-21 15:20:01
【问题描述】:

我正在尝试实现滑动删除与 Gmail 应用程序“滑动到存档”相同:

我尝试了很多教程,但没有一个能像 gmail 一样快, 我更喜欢不在外部库上工作。我该怎么做?

编辑:

到目前为止我的代码-

  ItemTouchHelper.SimpleCallback simpleItemTouchCallback = new ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT) {
                public boolean onMove(RecyclerView recyclerView,
                                               RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
//                    final int fromPos = viewHolder.getAdapterPosition();
//                    final int toPos = viewHolder.getAdapterPosition();
//                    // move item in `fromPos` to `toPos` in adapter.
                    return true;// true if moved, false otherwise
                }

            @Override
            public void onSwiped(RecyclerView.ViewHolder viewHolder, int swipeDir) {
                //Remove swiped item from list and notify the RecyclerView
                mAdapter.notifyItemRemoved(viewHolder.getLayoutPosition());
            }
        };
        ItemTouchHelper itemTouchHelper = new ItemTouchHelper(simpleItemTouchCallback);
        itemTouchHelper.attachToRecyclerView(mRecyclerView);

我已成功启用滑动手势,但我不知道如何在 viewHolder 下添加背景和图像。我试图在 item_XXX.xml 文件中放置另一个 FrameLayout,但在滑动时它会将整个项目与背景一起抛出。

【问题讨论】:

标签: android android-recyclerview


【解决方案1】:

RecyclerView Swipe 的简单代码:

     ItemTouchHelper.SimpleCallback simpleItemTouchCallback = new ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT | ItemTouchHelper.DOWN | ItemTouchHelper.UP) {

            @Override
            public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
                Toast.makeText(ListActivity.this, "on Move", Toast.LENGTH_SHORT).show();
                return false;
            }

            @Override
            public void onSwiped(RecyclerView.ViewHolder viewHolder, int swipeDir) {
                Toast.makeText(ListActivity.this, "on Swiped ", Toast.LENGTH_SHORT).show();
                //Remove swiped item from list and notify the RecyclerView
                int position = viewHolder.getAdapterPosition();
                arrayList.remove(position);
                adapter.notifyDataSetChanged();

            }
     };

然后使用以下语句为 recyclerView 设置回调:

ItemTouchHelper itemTouchHelper = new ItemTouchHelper(simpleItemTouchCallback);
 itemTouchHelper.attachToRecyclerView(rv);

【讨论】:

  • 对于令人窒息的动画,您可以使用 'adapter.notifyItemRemoved(position)' 而不是 'adapter.notifyDataSetChanged();'
  • @LMiranda 我遇到了 notifyItemRemoved(position) 的问题:当我调用它时,我刷过的项目被删除了,但是在列表中绘制了另一个元素,并且在适配器内部的大小list 实际上并没有改变,即使我确实删除了元素。例如,如果我有 3 个元素并且我删除了一个,那么适配器中的 getItemCount 仍然返回 3,然后再次重绘其中一个元素,有什么线索可以解释为什么会这样吗?
  • 您还需要从适配器内的列表中删除该项目。从列表中删除项目,然后使用 adapter.notifyItemRemoved(position) 和 'adapter.notifyDataSetChanged() 使其工作
【解决方案2】:

前几天我不得不这样做,但遇到了一些问题,所以我决定写一篇关于它的博客文章。不需要第三方库。

基本上,您不会通过onChildDraw 绘制“撤消状态”,而是通过ViewHolder 完成。此外,您实际上不会删除onSwipe 中的行,只需将其标记为“待删除”并通知适配器以“撤消状态”重新绑定它。同时,您发布 Runnable 实际上会在 x 秒内删除该行,除非按下撤消按钮...

【讨论】:

  • 很好的实现,即使我正在尝试类似于我能够在两个方向上实现滑动 Partial Swipe 但我们可以实现部分滑动,只是为了让用户知道他们可以执行相同的操作部分滑动?
  • 是否可以通过 onclick 代替 onswipe?
  • gmail 单选和多选 recyclerview 长按上下文操作模式弹出删除广告共享
  • 我已经实现了你的代码,如何将onClickListener添加到delete图标
  • 嗨@kjanderson2 它应该可以再次访问,我的网站有一些问题......
【解决方案3】:

这是您的onCreate 中设置“向左滑动删除”的最少代码:

binding.rows.adapter = adapter
ItemTouchHelper(object : ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.LEFT) {
    override fun onMove(v: RecyclerView, h: RecyclerView.ViewHolder, t: RecyclerView.ViewHolder) = false
    override fun onSwiped(h: RecyclerView.ViewHolder, dir: Int) = adapter.removeAt(h.adapterPosition)
}).attachToRecyclerView(binding.rows)

这假设您的 Adapter 类具有 removeAt 函数。我的看起来像这样:

fun removeAt(index: Int) {
    items.removeAt(index)   // items is a MutableList
    notifyItemRemoved(index)
}

感谢@RahulRaina 的 Java 回答!

【讨论】:

  • 这对我有用
【解决方案4】:

你可以试试Swipeable-RecyclerView

    SwipeableRecyclerView rv = findViewById(R.id.rv);
    rv.setLayoutManager(new LinearLayoutManager(this));
    rv.setAdapter(mAdapter);

    rv.setListener(new SwipeLeftRightCallback.Listener() {
        @Override
        public void onSwipedLeft(int position) {
            mList.remove(position);
            mAdapter.notifyDataSetChanged();
        }

        @Override
        public void onSwipedRight(int position) {
            mList.remove(position);
            mAdapter.notifyDataSetChanged();
        }
    });

两侧滑动的xml

<com.tsuryo.swipeablerv.SwipeableRecyclerView
    android:id="@+id/rv"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:leftBgColor="@color/colorAccent"
    app:leftImage="@drawable/ic_remove"
    app:leftText="Delete"
    app:rightBgColor="@color/blue"
    app:rightImage="@drawable/ic_check"
    app:rightText="Read"
    app:textColor="@android:color/white"
    app:textSize="20sp" />

【讨论】:

    猜你喜欢
    • 2020-09-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-05
    • 2019-09-22
    • 1970-01-01
    相关资源
    最近更新 更多