Android - Swipe to delete RecyclerView
Simple Code for 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();
}
};
Then set callback for recyclerView with below statements:
ItemTouchHelper itemTouchHelper = new ItemTouchHelper(simpleItemTouchCallback);
itemTouchHelper.attachToRecyclerView(rv);
Swiping to delete items of recyclerview doesnt work
Okay so I have finally found the problem.
I just had to initialize the ItemTouchHelper in the method where the RecyclerView
is built instead of in the onCreate method.
So this is what the code looks like:
private void buildRecyclerView() {
mRecyclerView = view.findViewById(R.id.recyclerview);
mLayoutManager = new LinearLayoutManager(getActivity());
mAdapter = new ExampleAdapter(mExampleList);
mRecyclerView.setLayoutManager(mLayoutManager);
new ItemTouchHelper(itemTochHelperCallback).attachToRecyclerView(mRecyclerView);
mRecyclerView.setAdapter(mAdapter);
}
ItemTouchHelper.SimpleCallback itemTochHelperCallback=new ItemTouchHelper.SimpleCallback(0,ItemTouchHelper.RIGHT | ItemTouchHelper.LEFT) {
@Override
public boolean onMove(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder, @NonNull RecyclerView.ViewHolder target) {
return false;
}
@Override
public void onSwiped(@NonNull RecyclerView.ViewHolder viewHolder, int direction) {
mExampleList.remove(viewHolder.getAdapterPosition());
mAdapter.notifyDataSetChanged();
}
};
RecyclerView swipe to delete still shows drawable with uncomplete swipe
Modified the onChildDraw() of the custom ItemTouchHelper.SimpleCallback by settings the bounds of the icon to 0 when unswiped with mIcon.setBounds(0, 0, 0, 0);
public class ItemDragSwipeCallback extends ItemTouchHelper.SimpleCallback {
private Drawable mIcon;
private final ColorDrawable mBackground;
public interface OnTouchListener {
boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target);
void onSwiped(RecyclerView.ViewHolder viewHolder, int direction);
}
private OnTouchListener mOnTouchListener;
public ItemDragSwipeCallback(Context context, int backgroundColor, int drawable, int dragDirs, int swipeDirs, OnTouchListener onTouchListener) {
super(dragDirs, swipeDirs);
mOnTouchListener = onTouchListener;
mIcon = ContextCompat.getDrawable(context, drawable);
mBackground = new ColorDrawable(context.getResources().getColor(backgroundColor));
}
@Override
public boolean onMove(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder, @NonNull RecyclerView.ViewHolder target) {
return mOnTouchListener.onMove(recyclerView, viewHolder, target);
}
@Override
public void onSwiped(@NonNull RecyclerView.ViewHolder viewHolder, int direction) {
mOnTouchListener.onSwiped(viewHolder, direction);
}
@Override
public void onChildDraw(@NonNull Canvas c, @NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder, float dX, float dY, int actionState, boolean isCurrentlyActive) {
super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive);
View itemView = viewHolder.itemView;
int backgroundCornerOffset = 25; //so mBackground is behind the rounded corners of itemView
int iconMargin = (itemView.getHeight() - mIcon.getIntrinsicHeight()) / 2;
int iconTop = itemView.getTop() + (itemView.getHeight() - mIcon.getIntrinsicHeight()) / 2;
int iconBottom = iconTop + mIcon.getIntrinsicHeight();
if (dX > 0) { // Swiping to the right
int iconLeft = itemView.getLeft() + iconMargin;
int iconRight = iconLeft + mIcon.getIntrinsicWidth();
mIcon.setBounds(iconLeft, iconTop, iconRight, iconBottom);
mBackground.setBounds(itemView.getLeft(), itemView.getTop(),
itemView.getLeft() + ((int) dX) + backgroundCornerOffset, itemView.getBottom());
} else if (dX < 0) { // Swiping to the left
int iconLeft = itemView.getRight() - iconMargin - mIcon.getIntrinsicWidth();
int iconRight = itemView.getRight() - iconMargin;
mIcon.setBounds(iconLeft, iconTop, iconRight, iconBottom);
mBackground.setBounds(itemView.getRight() + ((int) dX) - backgroundCornerOffset,
itemView.getTop(), itemView.getRight(), itemView.getBottom());
} else { // view is unSwiped
mIcon.setBounds(0, 0, 0, 0);
mBackground.setBounds(0, 0, 0, 0);
}
mBackground.draw(c);
mIcon.draw(c);
}
}
Prevent swipe to delete recyclerview item
Your RecyclerView
has RecyclerView.Adapter
attached to it. The adapter determines what information that the RecyclerView
can see and display. So, if item number 10, out of a 100-item backing array (managed by you) is swiped, the adapter can report that the array now contains 99 items and not ever present the swiped item to the RecyclerView
. That way the item appears to be deleted but is maintained internally and still accessible programmatically. How you manage that internal state is up to you and dependent upon your implementation.
If, however you want to not remove the item from the screen but just change its appearance, I think that you would need to look at the method onItemDismiss
that actually removes the item and notifies the adapter of the data change.
public void onItemDismiss(int position) {
mItems.remove(position);
notifyItemRemoved(position);
}
It is here that you would make the change. The item would stay in the adapter. You would also need to flag that position as "swiped" in case the view holders are recycle so you can maintain the visual "swiped" state.
public void onItemDismiss(int position) {
// Change background color, etc.
}
Take a look at code that has a "swipe to delete" function with "undo" for some ideas. Here is an example with a dialog that is called before deletion actually occurs if "Cancel" is clicked. There are many other examples of "undo" available. What you are trying to do can be considered to be an immediate and implicit "undo" with a visual change to the background.
If you want to have the item move back into position after a swipe, the following should work:
public void onItemDismiss(int position) {
notifyItemChanged(position);
}
Related Topics
How to Get Ndk-Gdb Working on Android
Logcat Not Displaying My Log Calls
How to Use the Android Accelerometer
Getting Results of Nearby Places from User's Location Using Google Maps API in Android
The Application Icon Does Not Show on Action Bar
Why Emulator Is Very Slow in Android Studio
Edittext in Listview Loses Focus When Pressed on Android 4.X
Mkdir() Works While Inside Internal Flash Storage, But Not Sd Card
Android Device Chooser -- Device Not Showing Up
How to Perform a Fade Animation on Activity Transition
Java.Lang.Securityexception: !@Too Many Alarms (500) Registered from Pid 10790 Uid 10206
Phonegap Plugin:How to Convert Base64 String to a Png Image in Android