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);
}
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 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.
How do i get a specific view inside of a RecyclerView item? For example I have a floating action button inside of a recyclerview item. The recyclerview card can swipe to trigger an event (new activity) and when the user swipes i am making the fab invisible. I want so that when the user returns back to the activity with the recyclerview, the fab is visible again.
I've tried to implement this a few ways, but for some reason it's taking the fab from the NEXT card/item and placing it on the original card/item that was swiped. This is a problem because the next card might have a different colored fab or no fab at all. What is happening is that it's taking the most recent viewholder item, even if the previous one is the one I want to deal with.
So i need a way to reference the fab in the current item. I'm currently setting it to currentFab = holder.mFab (but again, it's taking the most recent holder item even though it's not the one I pressed on). I need a way to reference the fab in a specific item.
I've tried something similar in the past, I've added the Swipe function in "onBindViewHolder ", Using a Swipe Library.
What I have made is, A CardView, Inside it there are 2 Strings, And a Button, this Button will be invisible according to specific conditions, So because it's inside onBindVewHolder, it was easy to make some edits on the button.
Here's a sample :
holder.Button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
holder.Button.setVisibility(View.GONE);
}
});
Ofcourse this isn't a "fully working code" it's just an example, Plus you didn't put any code that you have tried.
I have a recycler view of image views and upon longpress I try to give the image view a border. When I scrolldown and come back to the same object the boder is found on someother image.(It is ok coz... the recycler view deletes itself and creates back and so the position changes).
So what I did is I stored the image URl on long press and after scrolling back I drew the Border on the image based on the image URL.
Now the problem is the border that came previously(wrong position) is also drawn....how to get rid of it.
In simple terms. How to make the recyclerview forget the data changes?
(Notifydatasetchanged....Something like that)....
thankz in advance....
This is the problem caused by the position at which the boarder was made is not the same position after the scroll on RecyclerView you can easily fix this by allowing your object to remember if it was selected by long-press or not
Assume this is the class you have
class Item {
// here you already have your instance variables
// add another one
boolean isSelected;
}
when you long-press on an item make this instance variable of respective Item, true and provide it a boarder.
when you populate your List in RecyclerView's adapter what you can check is if the isSelected is true than make respective imageView have a boarder. otherwise don't
by doing so you will be independent of the position of the item with respective of the scroll. So your Item will retain the boarder which was actually selected.
I'm having a strange issue. I need to implement swipe to delete in my listview. When user swipes left/right, I need to animate a delete button into/out of the screen and then on delete button click I need to delete that item from listview.
I am using Commonswares [TouchList] (https://github.com/commonsguy/cwac-touchlist/tree/master/src/com/commonsware/cwac/tlv) library to achieve that. In onFling method it gets the position of the swiped row and send it to onRemove method in my activity. I can delete the item accurately. But if i animate the row at swiped position, multiple rows get effected. I am not able to fix this issue nor am I able to find any help.
Any help will be appreciated.
I had a similar issue to this which was down to Android's view recycling.
(A good explanation of it is available here)
To resolve I simply reset the animation in the item's OnResume method as I didn't need to retain the animation for the item which has scrolled out of view.