I have the RecyclerView, ItemTouchHelper and ItemTouchHelper.Callback instances to work together, and on swipe to left the selected item supposed to be removed (by this tutorial). The removal animation works, but only partly. First after swipe the item seems to be removed, but after that it reappers, and the list stays still the same:
Why can it happen?
Ensure these two statements
cartList.remove(position);
// notify the item removed by position
// to perform recycler view delete animations
// NOTE: don't call notifyDataSetChanged()
notifyItemRemoved(position);
are executing.
Related
I Have a RecyclerView that lets the user reorder its items when long taping using ItemTouchHelper.SimpleCallback, the problem is that UX wants to hide a handle on all item views BUT the dragged one, to provide some kind of feedback when the long tap is detected and the card can be dragged.
The issue is that as soon as I try to call notifyDataSetChanged() to make the items update acordingly and hide the handle icon, the Drag functionality stops working.
I tried calling this logic inside the onMove first, and then, inside a ItemTouchListener:onLongClick to try to run this logic and update the recycler before the item gets moved but the same result, as soon as I add a call to notifyDataSetChanged() the drag functionality stops working, any workarrounds to acomplish this functionlity?
To resolve the issue: replace the notifyDataSetChanged call with 2 calls to notifyItemRangeChanged(start, end) to update all views before and after the one being dragged, leaving the dragged one untouched, then the views are updated properlly and the drag gesture is not affected.
This could probably be solved using a DiffCallback too.
I want to catch a vertical swipe in an horizontal RecyclerView. Each item is simply a CircleImageView.
I found many resources on internet (like Drag and swipe with RecyclerView, Android - Swipe to delete RecyclerView) but those solutions ends deleting the item. I don't know if the term swipe requires also that the item is deleted or not.
What I want to achieve is to catch the swipe action on an item in the RecyclerView, but without delete the item itself from the RecyclerView.
I think that a good idea is to override the method onChildDraw() like suggested here: How to detect if Recyclerview item is being swiped?, but I can't understand how to achieve the behaviour I want.
My idea is: while the user swipes an item, the item itself moves in that direction; when the user end the touch event, the item has to come back to the original position (maybe changing the background color).
EDIT 1:
How to have swipe to delete and swipe to archive in two colours in Recyclerview Android probably can help, but it doesn't achieve the behaviour that I need. The item has to come back to the original position.
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);
}
Iet's assume an app that a RecyclerView with an associated ItemTouchHelper has been implemented and the following basic operation has occurred:
Drag invoked on a RecyclerView item and it's hovering over another "Target" item.
The drag item is released before an onMove callback is invoked.
The clearView callback is invoked where I was thinking the app would then complete a merge of the two items.
What I observe is that the drag item moseys back to it's pre-drop position.
I'd like to prevent the drag item from naturally gravitating back to it's original position before clearView gets a chance to do it's magic since having the drag item move back and then disappear is not desired.
What's the best way to implement this to prevent the drag item from moseying back to it's last position ahead of the merge operation?
So I was working with RecyclerView animations, and implemented an animation for when the items load into the List. I was wondering, if I can make an animation for when I replace the entire data set (an animation including the items joining and leaving the RecyclerView).
The correct way to remove an item from a recycler view is to remove the item from the data set and them inform the adapter that the item is removed. If you do this then the animation would happen similar to the animation that happens when you add an item.
myDataset.remove(position); // myDataset is List<MyObject>
mAdapter.notifyItemRemoved(position);//this line is important
If you are not using the second line then...
mAdapter.notifyDataSetChanged()
will be called and the animation will stop.
I have a RecyclerView and one item row needs to be updated like every second (SeekBar). So I call NotifyDataSetChanged once I update the data in the list. UI gets updated but the issue is that the RecyclerView scrolls so that this particular item is either at top or bottom of the screen.
I don't want RecyclerView to scroll.
// Update Data
mData.set(mData.indexOf(cardData), cardData);
// RefreshView
refreshView() {
runOnUiThread(new Runnable(){
notifyDataSetChanged();
}
);
You can update one item using notifyItemChanged(position); and u wont update all data in adapter, you will update only certain item
It's better to use the other notify methods from the RecyclerView.
For your usecase only swap out one item in your Adapter instead of all items and use notifyItemChanged(position).
This will be faster, the View won't scroll and if you ever will add an animation this will only work if you don't use notifyDataSetChanged
I got it working. I was having a card view above the recycler view.I just removed it. Now the whole screen is a recyclerView and I cannot see any auto scrolls.