The article http://android-developers.blogspot.in/2009/03/android-layout-tricks-3-optimize-with.html talks well about when to use View.
But I did not find a use case where I should replace the Inflate with ViewStub.
I didnot see any performance improvements when I replaced inflate with ViewStub.
Essentially ViewStubs just offer another way of doing things, or "achieving your goal". I find that you'll learn to use them when you are stuck and looking for help or another option. Otherwise if your code is doing what you want correctly without ViewStubs, then just forget about them for the time being.
There is no point forcing yourself to use extra options when you don't need them.
ViewStubs, in my own words, are "use once", temporary type of view holder. Use them when you want something to become visible on the screen only for that Activity's current life cycle.
There are other way you can accomplish that, but ViewStubs are very lightweights and simply offer a slightly different set of pros and cons compared to normal View objects.
Related
Suppose I have RecyclerView with hundreds of items. There are a few different view types. When I click on an item it has to change its UI. As I see it there are two options:
change the item to a different view type and notify the adapter that it changed so that it can inflate a new view to display the new state.
have both views in a single xml file. only one is visible at any time. Toggle between them using the setVisibility function when the state changes.
there are a lot of articles online about heterogeneous RecyclerViews using lots of view types, but i have yet seen one about the best practices when item views dynamically change and the RecyclerView becomes more heterogeneous over time.
which method is best to change an existing view in a recycler view? what are the tradeoffs?
The tradeoffs are pretty obvious.
Both UIs in a single View: depending on your views, this might:
Make the Views heavy to inflate and layout
Slow down the binding process, since you have to bind both UIs
Eventually, lag down the scrolling process.
On the other hand, you have a fast, precise control over what Views should change appearance at a certain time. Having both UIs in the same place allows for finer animations and transitions between one state and another.
Different View types: I think your case is not why view types were created in the first place - they are meant for having different childs at the same time, in different positions of the list. This:
Might slow down the transition. You have to be extremely careful on how you tell the adapter to reload the objects. As you can read anywhere, you might want to avoid notifyDataSetChanged(), which reloads any object, and rather use notifyItemChanged() or such. This requires some work and attention.
Does not allow (not easily, at least) for visual transition between one state and another.
The answer is that, IMO, only you can know. You should ask yourself:
Are these Views complex? Do they have a deep hierarchy? Would having both of them reduce performance (e.g. in the binding part)?
Would it be easy to understand which views are changed, and call notifyItemChanged(int position) in the second case? Reloading the whole dataset has a huge impact on performance, if you have lots of items.
Do you need some visual transition between one state and another? Maybe you want both UIs to fit into a single container (like different informations in a CardView)? If this is mandatory, then option 1 is better.
Do you have more than 2 UIs? If so, I would go with view types, so as not to host too many views in a single child layout.
and similar questions.
I'm looking for any examples or (even better) tutorials that can help me accomplish this. But I keep coming up short in my google searches, which has me worried that it's not even possible. So that's my first question: Can an expandable listview inflate a fragment when it expands and call it's onDestroy when retracted? and if so, can you please link me to any help with accomplishing this. Thanks
Here's a little visual of what I'm looking to do:
first, the general UI paradigm could be handled with an ExpandableListView. whether this gives you enough to match exactly what you need is TBD.
as for having fragments inside the list ... theoretically, in the list view's adapter's getView() method, you could do a FragmentTransaction.replace(), passing in a container ID that exists in the inflated view. i have not tried this.
that being said, i seriously doubt this will work. list views are smart about managing views. the views in the list are often destroyed and re-created as the user scrolls the list. adding fragments to a view is an expensive operation.
as an alternative, you might consider a ViewPager, which can hold fragments by design. it's not the UI you have spec'd above, but it's a common UI pattern used by many stock Google apps, so you know it's been tested.
I've noticed that you can accomplish better looking / more complicated view transitions by inflating a view and discarding (or saving) the previous view. However, I'm under the assumption that setContentView and startActivity do a better job at conserving memory while switching views. Is there a recommendation for what to use where?
take a look at http://www.androidguys.com/2008/07/09/inflation-is-a-good-thing/
It can be start point in your quest.
Which method is better?
1) Using a listview
2) Inflating and adding views in somelayout manually
IMO:
Use a listview.
Because
1) Listviews are standardised Android UI elements. They are recogniced by users as such, and used by developers that know how to use them. If any of them then has to maintain your code, (s)he'll thank you.
2) With some personal experience: Down the road of doing this manually: Lies pain and madness of the worst sort. Just use the tools avilable and save yourself the headache. ;-)
It deppends on what you want to do...
If your layout will be like a listview, make a listview with your custom adapters, more optimal and fast ;)
It depends on the use case, though adding views dynamically is going to be slower, also avoid deeper layout hierarchies.
For list view use ViewHolder to hold the views.
If you need your list to be customized or to have different look and feel than the android inbuilt list, then you can go for inflating and adding views in some layout manually. But efficiency wise , you can go with inbuilt one.
This is help you to know the things more better.
http://www.technotalkative.com/category/android/listview/
I am building a complex view based on dynamic data. Depending on the number of data elements in collections I am adding more views. Each of these subviews are complex and get inflated in the loop through the data collection.
This is of course inefficient and I would like to figure out a way to inflate the subview only once and then reusing them instead. Is this possible somehow?
PS: I do not want to build up the subviews in code (I know I could) because that would make things even messier due to the complexities and number of subviews, but if the performance would increase considerably I might take a look at that.
PPS: There is no visible performance problem but traceview that most of the time is spent inflating and if I can make it faster I would love to ;-)
you can check out the Google IO Session entitled 'The world of ListView'.
It explains very nicely how to prevent inflating the same view again and again, and how to reuse a particular view if it has been already inflated earlier.
Here is the link.
http://www.google.com/events/io/2010/sessions/world-of-listview-android.html
You can either download the .pdf file or view the video.
Hope it helps.
Regards,
Mahendra Liya.