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?
Related
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.
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.
I am having trouble finding the event to bind in the ListView adapter to scroll the listview to the bottom when a new item is added. When I initially populate the list its scrolled to the bottom which is correct but on an subsequent adds to the lists via a polling service it doesn't seem to stay on the bottom and I am forced to manually scroll. I am just wondering what events I need to hook into in order to set the index or automatically scroll to the bottom.
Okay I just noticed that when I add another item it pushes up 1 so it seems 1 item is always hidden when I add a new one, not quite sure how to fix this.
After doing more research I realised the error was due to me updating the collection on a different thread. Needed to be on the UIThread.
https://github.com/MvvmCross/MvvmCross-Tutorials/blob/master/Working%20With%20Collections/Collections.Droid/Views/PolymorphicListItemTypesView.cs
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 have a ListView backed by customized ArrayAdapter where each item has 2 LinearLayouts - one I call head, and the other one - body.
The body is hidden (gone) until user clicks on the row at which time it slides out. The second click (on the head) will hide the body. However if user clicks on the body it brings another activity. All of this works just fine, here comes the problem:
When user presses on body I want a visual indication of the action just the same way as regular list item will flicker an orange background when pressed. I'm not getting this by default since (my theory) the onPress event is intercepted by body's view and not processed by the list item.
The first thing I tried was to execute body.setBackground('#ff00ff') (never mind the color) in onPress event. That didn't work since (I suspect) there's no repainting after the call. Then I dig a little bit more and decided to use <selector/>-based background. I defined body_background.xml in drawable folder and assigned that to the body's background property.
There I noticed that background will only change if the even is processed by the list. For example if I set <item android:state_selected="true" android:drawable="#drawable/selected"/> then when I press on the head - the background of both elements (head and body) will change, however when I press on body - nothing.
So to summarize my question - how do I change background of the child element in the list item if I assign custom onClick handler to it? Any hints will be greatly appreciated
OK. Here's some more info I dig along the way.
I'm currently trying to switch implementation to ExpandableListView which provides the functionality I had to coded in (sliding body). The problem I may have here is that I have a fancy "endless" list implementation and I'm using ArrayAdapter#add method to dynamically add items to the list while scrolling (see my tutorial on androidguys.com) Well, the add method is missing from the BaseExpandableListAdapter so I need to see if adding items to internal array will work (it didn't for ArrayAdapter) possibly doing ExpandableListView#notifyChanged() will take care of that
The fact that I don't see anything when I'm directly using setBackgroundColor method is probably due to the subsequent call to startActivity call that halts all painting until new Activity is displayed
P.S. this has been resolved by switching to ExpandableListView. And may I add - it's beautiful! No need to invent anything