简体   繁体   English

RecyclerView ItemTouchHelper 滑动

[英]RecyclerView ItemTouchHelper on swipe

I'm trying to implement swipe to delete in a recycler view.我正在尝试在回收站视图中实现滑动以删除。 I have this code.我有这个代码。

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;
    }
}

However, the problem is that the row is deleted as it is swiped.但是,问题是该行在滑动时被删除。 I would like to maintain it there ie when the row is swiped, show the delete button and then the user can click on it, instead of swiping fully deletes it, instead show the delete button after the swipe.我想在那里维护它,即当滑动行时,显示删除按钮,然后用户可以点击它,而不是滑动完全删除它,而是在滑动后显示删除按钮。 Also, am trying to add the edit button as well but on the left, with the delete, any ideas how?另外,我也在尝试添加编辑按钮,但在左侧,删除后,有什么想法吗?

Create ItemTouchHelper and attach it to recyclerview.创建 ItemTouchHelper 并将其附加到 recyclerview。

Code to attach helper to RecyclerView将助手附加到 RecyclerView 的代码

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

Code of ItemTouchHelper class 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
            }
        }
    };

I find this new way of implementing swipe to delete quite friendly,that is implementing new ItemTouchHelper() in oncreate method.All you have to do is pass in the position of the item you want to delete in the recyclervew.我发现这种实现滑动删除的新方法非常友好,即在 oncreate 方法中实现 new ItemTouchHelper()。您所要做的就是在 recyclvew 中传入要删除的项目的位置。 See the the example code below.Here i implemented the new ItemTouchHelper() for it to delete any note i swipe right or left of my screen.请参阅下面的示例代码。在这里,我实现了新的 ItemTouchHelper() 以删除我向右或向左滑动屏幕的任何笔记。

here is the code:这是代码:

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 is the instance of my recyclerview rv_notes 是我的 recyclerview 的实例

To understand how you can implement it clearly ,follow the code in my github.Here is the link.要了解如何清楚地实现它,请按照我的 github 中的代码进行操作。这是链接。 https://github.com/sammymutahigicheru/NoteApp https://github.com/sammymutahigicheru/NoteApp

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM