Swipe to Dismiss for Recyclerview

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

Swipe to Dismiss for RecyclerView

As of v22.2.0, the Android support team has included an ItemTouchHelper class that makes swipe-to-dismiss and drag-and-drop pretty simple. This may not be as full-featured as some of the libraries out there, but it comes directly from the Android team.

  • Update your build.gradle to import v22.2.+ of the RecyclerView library

    compile 'com.android.support:recyclerview-v7:22.2.+'
  • Instantiate an ItemTouchHelper with an appropriate SimpleCallback

    ItemTouchHelper.SimpleCallback simpleItemTouchCallback = new ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT) {
    [...]
    @Override
    public void onSwiped(RecyclerView.ViewHolder viewHolder, int swipeDir) {
    //Remove swiped item from list and notify the RecyclerView
    }
    };

    ItemTouchHelper itemTouchHelper = new ItemTouchHelper(simpleItemTouchCallback);

    ** Note that the SimpleCallback takes in the directions that you want to enable drag-and-drop and the directions that you want to enable swiping.

  • Attach to your RecyclerView

    itemTouchHelper.attachToRecyclerView(recyclerView);

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 RecyclerViewis 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();
}
};

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

RecyclerView swiping to delete in Fragment?

I've fixed my issue by moving the Callback after I initialize my RecyclerView.

recyclerView = itemView.findViewById(R.id.recyclerView);
ItemTouchHelper.SimpleCallback ItemTouchHelperCallbackLeft = new RecyclerItemTouchHelper(0, ItemTouchHelper.LEFT, this);
new ItemTouchHelper(ItemTouchHelperCallbackLeft).attachToRecyclerView(recyclerView);

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

How to have swipe to delete and swipe to archive in two colours in Recyclerview Android

Use ItemTouchHelper to Implement the Gmail Like Feature

call the following function after setting the recyclerView

private fun initSwipe() {
val simpleItemTouchCallback = object : ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.LEFT or ItemTouchHelper.RIGHT) {

override fun onMove(recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder, target: RecyclerView.ViewHolder): Boolean {
return false
}

override fun onSwiped(viewHolder: RecyclerView.ViewHolder, direction: Int) {
val position = viewHolder.adapterPosition

if (direction == ItemTouchHelper.LEFT) {

//Logic to do when swipe left

} else {

//Logic to do when swipe right

}
}

override fun onChildDraw(c: Canvas, recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder, dX: Float, dY: Float, actionState: Int, isCurrentlyActive: Boolean) {

val icon: Bitmap
if (actionState == ItemTouchHelper.ACTION_STATE_SWIPE) {

//Drawing for Swife Right

val itemView = viewHolder.itemView
val height = itemView.bottom.toFloat() - itemView.top.toFloat()
val width = height / 3
if (dX > 0) {
p.color = Color.parseColor("#2F2FD3")
val background = RectF(itemView.left.toFloat(), itemView.top.toFloat(), dX, itemView.bottom.toFloat())
c.drawRect(background, p)
icon = BitmapFactory.decodeResource(resources, R.drawable.ic_archive)
val icon_dest = RectF(itemView.left.toFloat() + width, itemView.top.toFloat() + width, itemView.left.toFloat() + 2 * width, itemView.bottom.toFloat() - width)
c.drawBitmap(icon, null, icon_dest, p)
} else {

//Drawing for Swife Left

p.color = Color.parseColor("#D32F2F")
val background = RectF(itemView.right.toFloat() + dX, itemView.top.toFloat(), itemView.right.toFloat(), itemView.bottom.toFloat())
c.drawRect(background, p)
icon = BitmapFactory.decodeResource(resources, R.drawable.ic_delete)
val icon_dest = RectF(itemView.right.toFloat() - 2 * width, itemView.top.toFloat() + width, itemView.right.toFloat() - width, itemView.bottom.toFloat() - width)
c.drawBitmap(icon, null, icon_dest, p)
}
}
super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive)
}
}
val itemTouchHelper = ItemTouchHelper(simpleItemTouchCallback)
itemTouchHelper.attachToRecyclerView(YOUR_RECYCLER_VIEW)
}

Where
Object p is an object of paint Paint p = new Paint()
Hope this may help you.



Related Topics



Leave a reply



Submit