Are there any best practices on using the new RecyclerView animations together with a SQLite database?
In particular, I'm thinking about a pattern that's been around for a while now: sliding a list item off the screen to delete, and giving the user the option to undo.
Like in the Gmail app:
I don't think this is hard. My approach to solving this is in two parts, a custom view that shims around the adapter view, and a scroll listener on the recycler view.
The custom view is to handle the sliding item part. The key part is to mark the associated item for deletion when it is put into the slid state. I also like to allow for a second slide to dismiss the undo option.
The scroll listener on the recycler view simply deletes any marked items when onScrollStateChanged is called, you only need to care about changes away from SCROLL_STATE_IDLE. I prefer my deletion to be more lenient than the gmail implementation, so I post a delayed message on the scroll event rather than deleting straight away. You have to remember to cancel it if undo is pressed.
Oh, you also have to do any deletions if the screen is navigated away from.
You need to implements SwipeDismiss, use this library
SwipeDismissRecyclerViewTouchListener.java
On dismis you need implements a custom view or use visibility GONE from xml.
Related
I want to create a list, for example, To-Do List.
In this User is allowed to select/unselect an item, reorder according to their priority. In the current scenario, I am able to give them all of the above functionality using ItemTouchHelper.SimpleCallback.
My Challenge starts here -
When User selects an item(or right swipe it) I need to show that row disabled with strike-through text.
In such a case, I am changing its position and after that, all features like Drag & Drop, Swipe Left or Right should not work on that particular row.
And, If the user manually unselects it by tapping an icon, all the mentioned gestures should work.
I read about Method getSwipeDirs but didn't understand how to utilize it in my scenario.
I have gone through a couple of articles but all of them remove an item on swipe. Hence, I couldn't find the reference for my case.
If anyone has an idea about it and guide me further then it would be a great help! I am open
Note: I have used com.daimajia.swipe.SwipeLayout library just for left swipe as I want to enable full swipe just for Right direction. I am able to disable the library swipe by utilizing some of its methods. However, I still can not disable Drag/Drop or Right Swipe which I am using with help of ItemTouchHelper.SimpleCallback.
We can simply add the tag to the viewHolder of recyclerView and fetch the info from the tag for any particular row in the getMovementFlags method of ItemTouchHelper.Callback and manipulate drag/ drop or swipe flag as needed!
I'm using Recyclerview to show a list. I want to delete some items like IOS. In my listview template I have added a button to delete item which is invisible by default. In my activity I have another button attached at bottom (Not part of listview) and on tap of this button I want to make all delete buttons of listview visible.
My Question is how can I get reference to all delete buttons of listview in activity and is it the right way to do this?
Thanks
Assuming you have ViewHolders set up, you already have references to all the buttons in your list. All you have to do is to make them visible for every item in the list with a simple loop.
In case you haven't implemented ViewHolders I suggest you check out the documentation and take a look at some simple tutorials on how to use them.
On a side note. If I understood correctly you're making a bottom tab for your app and since you referenced iOS I gotta say this; Remember that Android and iOS are two unique operating systems with their own ways of handling things. Check out Googles pure Android documentation.
In your question title you say RecyclerView, but in your text you say ListView. The solution is similar either way, but it's best to be perfectly clear what you're doing.
In either case, there are at least two different solutions.
First, you could use a boolean flag to determine if all the the item buttons should be showing or not. You check this flag at the time the item view is inflated or created and toggle the button accordingly. If the boolean flag is ever changed, the easiest thing to do is tell the RecyclerView/ListView that the underlying data has changed and to redraw all the views. Call notifyDatasetChanged on the adapter.
The other thing you can do at the time the item buttons should change is iterate all the visible item views, find the button, and change its visibility. With RecyclerView, you can do this, and with ListView you can do this.
I was going through this thread on this topic :
RecyclerView Animation on Item Click
But I have one question on the technique used.
I tried implementing it based on solution above. Although the approach seems to work in the current view of my recyclerview. But as soon as i scroll further to Right (in my case its a Horizontal Recyclerview), i still see the view being expanded since the views are being recycled and the isExpanded value is still true for them. I was thinking shouldn't the isExpanded property be at the data being displayed, so that we don't keep the same state of the reused view ?
Curious to know, how does RecyclerView behaves when you scroll it to the next page.
Thanks,
Ok, basically you need to check each item "state" and prepare the recycled viewholder for the new item to bind.
Please have a look at my ExampleAdapter (in onBindViewHolder()) in my FlexibleAdapter, where you can also find basic click and long click listener already implemented as example.
Feel free to ask questions.
Recently I've improved and created a FlexibleAdapter pattern for all RecyclerView.
Very simple to use, just copy 2 classes in your common files + some xml in order to enable the selection (Single/Multi) as it was for ListView.
Please have a look at the description and full working example: https://github.com/davideas/FlexibleAdapter
I'm working on creating a swipe-to-dismiss list view adapter. My basic methodology is to wrap the list item's view as the second view in a ViewPager and provide the necessary callbacks in the item change listener of the ViewPager. Through much pain I've got the View recycler working as intended, as well as ViewHolder and ViewBinder patterns implemented. I even managed to keep the ListView from taking over the touch events while the ViewPager is being scrolled without having to make a custom subclass of ListView (I can do it all from the Adapter).
Where I'm running into trouble is getting the selector and the OnItemClickListener to work. After looking at ListView's source it seemed that by overriding the ViewPager's hasFocusable() method to always return false (later on I'll pull this value from the child view) these things should have been reenabled. Unfortunately this is not the case. I've tried the setDecendantFocusability() workaround and I'm still stuck.
I'd like to avoid having to extend ListView if possible to provide the greatest amount of modularity. For similar reasons I don't want to add the selector to the ViewPager's background (if the dev changes the ListView's selector this wouldn't be reflected). Essentially I'm looking to make the ViewPager code transparent between the ListView and child View. Any ideas?
You are saying that you are making each list item a view pager, so that you can implement swiping to delete? If so... no no, this is not what view pager is for. First sorry it is just not intended to be used as an item in a list. Second it is for switching between views, not swiping to delete.
Unfortunately we don't have a sample code to show how to do this, but you can look at the platform's implementation of the notification pane or recent apps to get some ideas.
I am attempting to update a ListView fast at 10fps. I use ListView properly (I think!) as covered in this google talk http://www.youtube.com/watch?v=wDBM6wVEO70&t=17m38s with Guy Romain.
I have been attaching listeners (in my extension of BaseAdapter's getView()) to a few widgets I place inside my custom view items. This works perfectly at 1s refresh, but at 0.1s refresh, most of the clicks are lost.
I've assumed this is because ListView is recycling things like crazy, and so my view with a registered listener is getting trashed and replaced with a new view, albeit with the same listener, before it can handle any clicks.
Since the List itself receives clicks perfectly (I use them to collapse and expand individual entries with visibility), I thought there must be a way to determine from the View received in onListItemClicked() what subview (widget) the mouse had actually been over when the click was received. I could then handle the clicks here in the persistent ListActivity object.
I've tried various variants of focusability to try to change the View v received in onListItemClicked(), but nothing has yet worked.
Does anyone know how to do this, or a functional alternate approach?