I have a ListView with layouts in them. Sometimes the layouts need to look one way, sometimes the other. They are mainly text laid out in different areas with different weights sizes etc. The ratio of main views compared to other views is about 5:1. When it needs to be changed only 2/3 of the whole view changes.
I think I have two options :
(the way it is now) One layout(so it never has to be re-inflated, as the recycled views are all the same) and the 2nd 2/3 of the view is hidden until it is needed to be changed, then code will reveal it and hide the original 2/3 of the view.
(other way) Two layouts, with the 1/3 layout duplicated, and each having its on other 2/3. Then when one of the different layouts needs to be used, the old view from the ListView recycler gets thrown away and a new correct view is inflated, and back again when the list is moved.
So what I am asking here is that is it better to hide/show parts of the same layout to prevent the recycler in a ListView from inflating more layouts, or have two cut-down layouts with no extra hidden views, and have them inflated when they are needed?
If the TextViews are the main part of those layouts, I don't think there is going to be a big difference in performance so you could go either way. I would go with option two because:
The ratio between the number of normal rows layout vs special rows is big. If you keep the single layout approach then you'll have to modify the layouts in code for each of the rows, normal or special, because you could be dealing with a recycled View that has 2/3 part hidden when it's time to show a normal one(so you end up modifying the layout each time). If you were to use the second option then you could eliminate this part from the getView method and simply use a switch to see with what row type you're dealing with(no more modification of the row layout each time in the getView method, you let the ListView handle that by providing you with the correct type of row layout). Don't worry about inflating another layout file(once), this isn't the performance hit to be afraid of.
Using one type of layout it means you're having Views remaining in memory even if the user doesn't see them(so you may be preventing the ListView from inflating more Views(only one time, in fact) but at the same time you're occupying more memory with the ones you even don't show to the user). The first option has the advantage that the binding of data to the row is more simple as you have all the views at your disposal(even if the user doesn't see a part of them) instead of the second option, where you would have to see which data need to be shown based on row type.
Code readability. Having two row types and testing to see which one you get in the getView method it's more meaningful as you see what logic you have for each type of row. Also, it will be better if you plan to change those row layouts in the future or add more row types.
The ListView does a great job on recycling views as long as you help it with providing the row types.
Edit: The ListView will keep a recycled view for each type you declare in the adapter. So the ListView will inflate the second layout only the first time it finds it in the ListView, next time when it will need a row with with type it will use the recycled one(and it will maintain 2 types of recycled views, the first and second row type).
Actually this little bit of extra GC IMHO should not be the driver for your decision.
I would go the route that is easier to maintain and understand.
Also there is an nice useful include tag in xml like this:
<include
android:id="#+id/abc"
android:layout_height="wrap_content"
android:layout_width="fill_parent"
layout="#layout/abc" , where abc = the xml file you want to include
/>
Related
My app contains a viewpager and each page fragment is laid out as so:
<ScrollView>
<LinearLayout>
...
other views
One of these 'other views' is a LinearLayout populated at runtime in a loop. Each item is inflated from xml. I've determined each call to LayoutInflater.inflate() is taking avg 4-6 ms. Between all my fragments and some containing more than one of these 'dynamically populated lists' i'm inflating 40-50 of these child layouts during startup and it's adding up to a lot of skipped frames.
I'm looking for a less expensive way to create all these views.
All the child views within one list are the same, is it possible to inflate one and copy it to another instance in a way that is faster than calling inflate()?
Is it possible to reuse these views similarly to the way a listview does?
One last potential solution, would it be faster to create these child views manually rather than inflate them from xml?
So to summarize the question, looking for the least expensive ways to create views in code. thanks for reading.
I am going to start one app where my activity page will contain "n" grouped views. Grouped view means "collections of views (i.e. One group can have TextView+Button+ImageView)". So the page will have "n" number of such grouped views.
I need suggestions like what would be the best practice to implement this. I could think of below ones:
1) Should a ScrollView be used (Then I will have to create groups in runtime and place one under another)?
2) Or a ListView be used (Then how can I accommodate the height of each row as grouped views height may differ from each other?)
Or is there any other way I can go along with?
Appreciate the suggestions and any sample examples if have. Advance Thanks.
Both options would work, it really depends on your use case.
Place a vertical LinearLayout inside of a ScrollView and add your grouped-views to the LinearLayout. I would recommend this if you have a relatively small number of such views (not necessarily a fixed number, but small enough that you wouldn't have to scroll many "pages" to see them all). Make sure the ScrollView has android:layout_height="match_parent" and the LinearLayout has android:layout_height="wrap_content".
If the number of grouped-views is not small, you could use a ListView and make an Adapter for it. This lets you take advantage of ListView's automatic view recycling when items get scrolled off screen.
For either case, make an XML file for just the grouped-views. In code, you would get a LayoutInflater object (usually by calling Activity.getLayoutInflater()) and call inflate(R.layout.your_grouped_views, null). If using the LinearLayout, you would add it in code with one of the LinearLayout.addView(..) methods; if using the ListView, your adapter would return the whole thing from getView(...).
create one xml layout containing the constant elements of your group view.
in you main xml layout which will be the contentView of your application, put a ScrollView and a single LinearLayout.
then in the program inflate as many views of your group view as you want.
For your answer i want to give you referance of this website, on this website you can learn create dynamic view in android...
Say I have an activity showing informations on an object: the name, a little description, a photo. Below this informations I have a list of comments. Obviously the number of comments displayed is not fixed and the list have to be created dynamically. Now I want ALL the activity layout to be scrollable, so I added a ScrollView as parent of all other Views. But in this way, I can't use a ListView to show the comments, because it's not possible (or it's very discouraged) to wrap a ListView inside a ScrollView. I'm compelled to use a LinearLayout, cycling on the comments list and inflating (I want to keep layouts in xml) multiple times the same layout, which brings to other drawbacks like the confusion on items ids.
Note well that even trying to reduce the complexity showing a prefixed number of items in the list (say showing N most recent), it would be very annoying to embed in the xml definition of the LinearLayout a fixed number of list items, because changes in N would affect both code and xml.
Which could be a optimum design to face all this problems:
Keep all the activity layout scrollable.
List a variable non pre-fixed number of items in a portion of the UI.
Keep the definition of the list item layout in the xml.
Prevent inflating multiple times the same layout.
I can't figure out that in android it is not possible or it's necessary to use some kind of workaround to achieve this common behavior.
I typically organize my code/logic by a fragment represent one layout. Now I am in need of few relatively simple forms to get input data from user, which are somewhat related in purpose.
Say I hav 3 screens, and I could create 3 fragments to handle them (display view, read input, submit, ..). Or should I use one fragment, and use FrameLayout create a stack of layouts. I was thinking like, stacking all 3 views and hide/display the view I like. But the documentation say
Generally, FrameLayout should be used to hold a single child view,
because it can be difficult to organize child views in a way that's
scalable to different screen sizes without the children overlapping
each other
Any good way to do this or should I create multiple fragments for this (the down side of this is lot of small classes and repeated code. I may use a base class, still like to explore other options)
Thanks.
It sounds like you don't really care that much if the views overlap each other in the FrameLayout, or in fact they are supposed to overlap because you expect to be showing only one at a time. FrameLayout can certainly display stacked child views that each take up its full width and height just fine, and if you set the visibility of the unused views to INVISIBLE or GONE, they will not intercept screen presses or take focus if they happen to be located above the visible view the user is interacting with.
On the point of readability and code maintenance, I think swapping fragments makes more sense though, even if there is more memory overhead. The layout management can be encapsulated within the individual fragments, and you do not need to worry about showing/hiding views, as fragment transactions will take care of that aspect.
Can any one explain the difference between Scroll View and List View? When to use which one? And which one is more efficient?
ScrollView is used to put different or same child views or layouts and the all can be scrolled.
ListView is used to put same child view or layout as multiple items. All these items are also scrollable.
Simply ScrollView is for both homogeneous and heterogeneous collection. ListView is for only homogeneous collection.
They're completely different.
A ScrollView is simple a scrolling container you can use to scroll whatever you put inside it, which might be a list of items, or it might not.
http://developer.android.com/reference/android/widget/ScrollView.html
A ListView is very specifically designed to hold lists, where items typically look the same (or at least follow a pattern, e.g. section headings). ListView is also designed to connect to a data source of some sort, SQLite, array, content provider etc. ListView can scale to handle enormous numbers of list items.
http://developer.android.com/resources/tutorials/views/hello-listview.html
If you have data you need to show in a list, use a ListView. If you just need scrolling content, then a ScrollView is probbaly enough.
ListView:-
In ListView You can manage layout of items in xml easily that you want to display in list.
You are required to tell the adapter ho many item you want in your display list.
You can design for both homogenous as well as heterogenous views depending on your requirement by overrifing getItemViewType() method of Adapter.
In ListView items in list are created according to screen size. i.e How many items can appear on screen are created additional views(items) are created when list is scrolled at runtime. The views that are displayed once are cached when they move out of screen and when list is scrolled back to previous state the same views are displayed but this time view are not created rather they are fetched from cache.
ScrollView :-
Cache concept is not applicable with ScrollView.
All views are created at once when they come to screen and are not cached when they move out of screen while scrolling. They are present in memory(main) that may lead to memory leak because the number of objects created are not being destroyed by garbage collector since they are being referenced untill you are on same page.
Although you can create both homogenous as well as heterogenous views. If there are more items to be displayed in your list it would be tedious to manage the layout whether you are designing in xml or creating dynamically using Java code.
It is preferable to use scrollview if you have a single page that does not contain list of items e.g registration form, reservation form but that view is larger than the screen size then put ScrollView as parent view also keep in mind that ScrollView can have only one direct child layout/view.
ScrollView simply places its contents in a scrollable container, you can edit it's contents only by adding views to it.
ListView is a class that uses an adapter which handles creating the views for your data objects, you only need to edit the data, and the layout modifications are done automatically by the adapter.
ScrollView should be used when you have a screen (ex: a form with multiple fields) that do not fit into one screen on small devices, as such scrollview offers the user the possibility to scroll down.
ListView should be used when representing sets of data.
You can read about these at http://developer.android.com/guide/index.html
A ListView is backed by an Adapter, which contains a DataSource. This allows you to easily display data in rows.
A ScrollView allows you to put content inside of it, and if the content exceeds the size of the ScrollView, it will allow the user to scroll.
They both have their uses, but it depends on what you are trying to do.
Since an image worth a thousand words, here are perfect real life examples:
Listview is like the Kijiji app
Scrollview is like the EBay app
Also, see a scrollview like a billboard or a wall, where you can put bunch of different stuff on it.
And a listview is more like a result page: results are all of same nature, therefore they fit perfectly in a listview. Like a contacts list: they all share the same structure; phone number name address, etc....