【问题标题】:RecyclerView ItemTouchHelper on swipe滑动时的 RecyclerView ItemTouchHelper
【发布时间】:2019-09-27 06:35:14
【问题描述】:

我正在尝试在回收站视图中实现滑动删除。我有这个代码。

public abstract class SwipeToDeleteCallback extends ItemTouchHelper.Callback {
    private Context context;
    private Paint clearPaint;
    private ColorDrawable background;
    private int backgroundColor;
    private Drawable deleteDrawable;
    private int intrinsicWidth;
    private int intrinsicHeight;

    public SwipeToDeleteCallback(Context context) {
        this.context = context;
        background = new ColorDrawable();
        backgroundColor = Color.parseColor("#DB3236");
        clearPaint = new Paint();
        clearPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
        deleteDrawable = ContextCompat.getDrawable(this.context, R.drawable.ic_delete_white_24dp);
        intrinsicWidth = deleteDrawable.getIntrinsicWidth();
        intrinsicHeight = deleteDrawable.getIntrinsicHeight();
    }

    @Override
    public int getMovementFlags(@NonNull RecyclerView recyclerView,
                                @NonNull RecyclerView.ViewHolder viewHolder) {
        return makeMovementFlags(0, ItemTouchHelper.LEFT);
    }

    @Override
    public boolean onMove(@NonNull RecyclerView recyclerView,
                          @NonNull RecyclerView.ViewHolder viewHolder,
                          @NonNull RecyclerView.ViewHolder viewHolder1) {
        return false;
    }

    @Override
    public void onChildDraw(@NonNull Canvas canvas, @NonNull RecyclerView recyclerView,
                            @NonNull RecyclerView.ViewHolder viewHolder, float dX, float dY,
                            int actionState, boolean isCurrentlyActive) {
        super.onChildDraw(canvas, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive);

        View itemView = viewHolder.itemView;
        int itemHeight = itemView.getHeight();

        boolean isCancelled = dX == 0 && !isCurrentlyActive;

        if (isCancelled) {
            clearCanvas(canvas, itemView.getRight() + dX, (float) itemView.getTop(),
                    (float) itemView.getRight(), (float) itemView.getBottom());
            super.onChildDraw(canvas, recyclerView, viewHolder, dX, dY, actionState,
                    isCurrentlyActive);
            return;
        }

        background.setColor(backgroundColor);
        background.setBounds(itemView.getRight() + (int) dX, itemView.getTop(),
                itemView.getRight(), itemView.getBottom());
        background.draw(canvas);

        int deleteIconTop = itemView.getTop() + (itemHeight - intrinsicHeight) / 2;
        int deleteIconMargin = (itemHeight - intrinsicHeight) / 2;
        int deleteIconLeft = itemView.getRight() - deleteIconMargin - intrinsicWidth;
        int deleteIconRight = itemView.getRight() - deleteIconMargin;
        int deleteIconBottom = deleteIconTop + intrinsicHeight;

        deleteDrawable.setBounds(deleteIconLeft, deleteIconTop, deleteIconRight, deleteIconBottom);
        deleteDrawable.draw(canvas);

        super.onChildDraw(canvas, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive);
    }

    private void clearCanvas(Canvas canvas, Float left, Float top, Float right, Float bottom) {
        canvas.drawRect(left, top, right, bottom, clearPaint);
    }

    @Override
    public float getSwipeThreshold(@NonNull RecyclerView.ViewHolder viewHolder) {
        return 0.7f;
    }
}

但是,问题在于该行在滑动时被删除。我想将它保留在那里,即当滑动该行时,显示删除按钮,然后用户可以单击它,而不是完全滑动删除它,而是在滑动后显示删除按钮。另外,我也在尝试添加编辑按钮,但在左侧,删除,有什么想法吗?

【问题讨论】:

    标签: android android-recyclerview itemtouchhelper


    【解决方案1】:

    我发现这种实现滑动删除的新方法非常友好,即在 oncreate 方法中实现 new ItemTouchHelper()。您所要做的就是在回收站中传递您要删除的项目的位置。请参阅下面的示例代码。这里我实现了新的 ItemTouchHelper() 以删除我在屏幕上向右或向左滑动的任何笔记。

    代码如下:

    new ItemTouchHelper(new ItemTouchHelper.SimpleCallback(0,
                ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT) {
            @Override
            public boolean onMove(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder, @NonNull RecyclerView.ViewHolder viewHolder1) {
                return false;
            }
    
            @Override
            public void onSwiped(@NonNull RecyclerView.ViewHolder viewHolder, int i) {
                noteViewModel.delete(noteAdapter.getNoteAt(viewHolder.getAdapterPosition()));
                Toast.makeText(MainActivity.this, "Note Deleted", Toast.LENGTH_SHORT).show();
            }
        }).attachToRecyclerView(rv_notes);
    

    rv_notes 是我的 recyclerview 的实例

    要了解如何清楚地实现它,请按照我的 github 中的代码进行操作。这里是链接。 https://github.com/sammymutahigicheru/NoteApp

    【讨论】:

      【解决方案2】:

      创建 ItemTouchHelper 并将其附加到 recyclerview。

      将帮助程序附加到 RecyclerView 的代码

      itemTouchHelper = new ItemTouchHelper(simpleCallback);
      itemTouchHelper.attachToRecyclerView(recyclerView);
      

      ItemTouchHelper 类的代码

      ItemTouchHelper.SimpleCallback simpleCallback = new ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.LEFT) {
      
              private void drawText(String text, Canvas c, RectF button, Paint p) {
                  float textSize = 30;
                  p.setColor(Color.WHITE);
                  p.setAntiAlias(true);
                  p.setTextSize(textSize);
      
                  float textWidth = p.measureText(text);
                  c.drawText(text, button.centerX() - (textWidth / 2), button.centerY() + (textSize / 2), p);
              }
      
              @Override
              public void onChildDraw(Canvas c, RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, float dX, float dY, int actionState, boolean isCurrentlyActive) {
                  if (actionState == ItemTouchHelper.ACTION_STATE_SWIPE) {
      
                      View itemView = viewHolder.itemView;
                      Paint p = new Paint();
      
                      if (dX > 0) {
                          c.drawRect((float) itemView.getLeft(), (float) itemView.getTop(), dX,
                                  (float) itemView.getBottom(), p);
                      } else {
                          RectF rightButton = new RectF(itemView.getRight() - 200, (itemView.getTop() + dpToPx(4)),
                                  (itemView.getRight() - dpToPx(4)), (itemView.getBottom() - dpToPx(8)));
                          p.setColor(ContextCompat.getColor(MainActivity.this, R.color.colorAccent));
                          c.drawRoundRect(rightButton, 10, 10, p);
                          drawText("Del", c, rightButton, p);
                      }
      
                      // Fade out the view when it is swiped out of the parent
                      final float alpha = 1 - Math.abs(dX) / (float) viewHolder.itemView.getWidth();
                      viewHolder.itemView.setAlpha(alpha);
                      viewHolder.itemView.setTranslationX(dX);
                  } else {
                      super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive);
                  }
              }
      
              @Override
              public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
                  return false;
              }
      
              @Override
              public void onSwiped(final RecyclerView.ViewHolder viewHolder, int direction) {
                  final int position = viewHolder.getAdapterPosition();
                  if (direction == ItemTouchHelper.LEFT) {
                      AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
                      builder.setMessage("Are you sure to delete?");
                      builder.setPositiveButton("REMOVE", new DialogInterface.OnClickListener() {
                          @Override
                          public void onClick(DialogInterface dialog, int which) {
                              adapter.notifyItemRemoved(position);
                              mProductViewModel.delete(adapter.getItem(position));
                              return;
                          }
                      }).setNegativeButton("CANCEL", new DialogInterface.OnClickListener() {  //not removing items if cancel is done
                          @Override
                          public void onClick(DialogInterface dialog, int which) {
                              adapter.notifyItemRemoved(position + 1);
                              adapter.notifyItemRangeChanged(position, adapter.getItemCount());
                              return;
                          }
                      }).show();  //show alert dialog
                  }
              }
          };
      

      【讨论】:

        猜你喜欢
        • 2017-12-11
        • 2017-02-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-01-25
        • 2018-01-10
        相关资源
        最近更新 更多