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.
Code to attach helper to RecyclerView
itemTouchHelper = new ItemTouchHelper(simpleCallback);
itemTouchHelper.attachToRecyclerView(recyclerView);
Code of ItemTouchHelper class
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. 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.
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
To understand how you can implement it clearly ,follow the code in my github.Here is the link. https://github.com/sammymutahigicheru/NoteApp
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.