I have a serious problem with a custom view i use in an expandableListView. I use an adapter that extends BaseExpandableListAdapter. The custom view changes its state depending on if it is being consulted or modifying. The state change involves animation and show/hide of ui parts.
The problem is that even thought i let only two views, when i click on the second view i order to make it change its state, the adapter calls the getViewGroup fo the two views but systematically inverting the corresponding model data ids.. .witch makes the ui to animate again...
I precise that i don't use the viewholder pattern since the custom view has its own internal references to the controls to be updated.
Any idea would be appreciated?
i found out the solution, everytime the model changes i called notifyDataChanged() which makes the entire listview to be redrawn
Related
This question already has answers here:
Android Recyclerview vs ListView with Viewholder
(7 answers)
Closed 3 years ago.
I was reading about the difference b/w recyclerview and listview and found out that recyclerview is faster than listview.
I tried to search online but not found any satisfactory answer I know it is used ViewHolder pattern and Notifying adapter but what does it does intearlly so it is faster?
Recycler View you could say is an efficient way to create list of views.
If you have 1000 items like ur contact list , and If ur visible screen can show only 10 items at once, it will Create only 10+1 (or +2) Views and as u scroll , items/views that left will be reused (not create) to show new data.
Recycler View by default does this, where as List View by default doesn't do.
There are some differences between these two views.
ListView is a bit heavy and it has a lot of responsibilities. Whenever we have to handle the list, such as to configure it in some way, the only way to do this is through the ListView object or inside the adapter.
A lot of bad things in the ListView were fixed or changed in the RecyclerView. It’s more efficient by default, the layout is separated and we have more possibilities over the data set inside the adapter.
These are some crucial differences between ListView and RecyclerView:
1 ViewHolder
The ViewHolder pattern allows us to make our list scrolling act smoothly. It stores list row views references and, thanks to this, calling the findViewById() method only occurs a couple of times, rather than for the entire dataset and on each bind view.
The RecyclerView’s adapter forces us to use the ViewHolder pattern. The creating part (inflating the layout and finding views) and updating the views is split into two methods — onCreateViewHolder() and onBindViewHolder().
The ListView, on the other hand, doesn’t give us that kind of protection by default, so without implementing the ViewHolder pattern inside the getView() method, we’ll end with inefficient scrolling in our list.
2 LayoutManager
The LayoutManager takes responsibility for layouting row views. Thanks to this, RecyclerView doesn’t have to think about how to position the row view. This class gives us the opportunity to choose the way that we want to show the row views and how to scroll the list. For example, if we want to scroll our list vertically or horizontally, we can choose LinearLayoutManager. For grids, it is more suitable to choose the GridLayoutManager.
Previously, with the use of the ListView, we were only able to create a vertical-scrolling list, so it wasn’t that flexible. If we wanted grids on our list, we had to choose the other widget for that — GridView.
3 ItemDecoration
A duty of the ItemDecoration is simple in theory – add some decorations for the list row views – but in practice, it’s that simple to implement if we want to create a custom one. In this case, we should extend the ItemDecoration class and implement our solution. For example, the RecyclerView list has no dividers between rows by default and it’s consistent with the Material Design guidelines. However, if we want to add a divider for some reason, we can use DividerItemDecoration and add it to the RecyclerView. In case we use the ListView, we have to figure out rows decorations by ourselves. There is no helper class like ItemDecoration for this widget.
4 ItemAnimator
The last but not least component of RecyclerView that I want to mention is ItemAnimator. As we can expect, it’s handling row views animations like list appearance and disappearance, adding or removing particular views and so on. By default, RecyclerView’s list animations are nice and smooth. Of course, we can change that by creating our own ItemAnimator, which is also not that easy. To make it easier, we should extend the SimpleItemAnimator class and implement the methods that we need (just add animations to a ViewHolder’s views). To be honest, implementing animations on the ListView was a pain. Again, we had to figure out how we want to handle them.
5 Notifying adapter
We have a couple of cool notifiers on the RecyclerView’s adapter. We are still able to use notifyDataSetChanged() but there are also ones for particular list elements, like notifyItemInserted(), notifyItemRemoved() or even notifyItemChanged() and more. We should use the most appropriate ones for what is actually happening, so the proper animations will fire correctly.
Using ListView, we were able to use just notifyDataSetChanged() on the adapter and then had to handle the rest ourselves, again.
Because of ViewHolder Pattern.
Thats was the simplest answer. Now for some details.
What recycler view does is what it's name indicates "Recycle", yes it recycles items, and it does it with the help of ViewHolder Pattern.
By Using ViewHolder we do-not need to call findViewByID() every time we go through getView()method. The reference for all rows are stored in-memory. This increases the performance significantly, as findViewByID()is a heavy process.
Hope this clears your confusion.
I have a ListView which onItemClick selected item changes its layout, pops different buttons. If any other item is selected, the previous selected one returns to normal. My ListView adapter works fine but refreshing the whole list with notifyDataSetChanged() in my adapter takes too much time.
My problem is to refresh only the changed items in the ListView.
And also I would like to have suggestions for better scrolling performance.
try to implement View Holder Pattern it increases the performance of loading and scrolling of ListViews
Making ListView Scrolling Smooth | Android Developers
Using lists in Android (ListView) - Tutorial - Vogella
from the docs:
Your code might call findViewById() frequently during the scrolling of ListView, which can slow down performance. Even when the Adapter returns an inflated view for recycling, you still need to look up the elements and update them. A way around repeated use of findViewById() is to use the "view holder" design pattern.
you can define one method in adapter class which will return current item view. in onitemclick use this method to make changes in clicked item. You can define class view type class variable in activity and store previous view there...
ListView scrolling performance slows down when widgests like textviews, images are at the bottom of the layout hierarchy.
So for improving list performance one should design item xmls with minimum layout tree levels.
I'm trying to show an animation with all Views that I've created from an adapter. When I scroll down, it shows the animation correctly, but when I scroll up, I see these Views recreate themselves and show the animation again. Then, when I scroll down, it happens again.
My assumption is that the mechanism of creating a View from an adapter is to load the View into memory; just the group of Views which are on screen right now (but above and below views are not loaded into memory). These will be loaded again when I scroll to these views, right?
Is there any way to fix this problem?
PS: Sorry for my English, I hope you understand my problem.
My assumption is that the mechanism of creating a View from an adapter
is to load the View into memory; just the group of Views which are on
screen right now (but above and below views are not loaded into
memory)
That's somewhat correct: a ListView will not try to visualize any data that isn't (at least partially) visible. It also 'recycles' views, meaning that any view that isn't currently used to present data to the user and is of the same 'type' as the next data item, may get reused.
Hence you shouldn't rely on persisting data with or make any assumptions about the existence of particular views. In stead, use something that's separate from the views; e.g. the dataset you're visualizing.
Quite often, you'll supply a list of POJOs to a BaseAdapter or ArrayAdapter. You could simply add a boolean to the POJO indicating whether it should animate or not, and change that whenever the animation for that particular item finishes. Alternatively, you could keep track of these values in a separate collection (which is probably the more straightforward approach if you're dealing with a Cursor as data source rather than POJOs).
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 want to do something like mylistview.setElementsofView(0).getElementById.setColor("black");
currently the only way I know of doing this is setting up a custom list view adapter, setting up constructors, do conditional checks to see if view is populated, then do stuff in that view
this seems very convoluted, when other parts of the listview are so easily accessible.
is there some inherited function I can access in listview to allow me to access the elements of a particular view without a custom adapter?
Thanks for any insight
The short answer to your question:
is there some inherited function I can access in listview to allow me to access the elements of a particular view without a custom adapter?
unfortunately is no.
Why do you think setting up a custom adapter is so convoluted? Just make the customized adapter class a nested class within your activity. Most likely, you'd only be looking at overriding the getView() method. In the end, you'll spend a lot less time doing this than looking for a "simple" solution.
What about
myListView.getChild(index).setColor("black");