I have a LinearLayout with a nested listview which looks like this:
<LinearLayout ... >
<LinearLayout>
</LinearLayout>
<ListView>
</ListView>
</LinearLayout>
The problem is that the listview owns the scrollbar (so only content in the listview is scrollable) but i actually want the parent LinearLayout to own the scrollbar (so making the entire content scrollable).
Wrapping parent ListView in a ScrollView hasn't been successful because the ScrollView doesn't recognize ListView height (which looks like is rendered at running time)
Thanks
Edit: SOLVED My perfect solution was using a MergeAdapter, as advised by Barak
You can use CommonWares MergeAdapter which allows you to define views and list adapters, pour them into the MergeAdapter and get a single list adapter out, containing everything you poured in, and it scrolls as one list.
A previous answer about MergeAdapter I gave with some instructions is here
You could replace the Listview with a Tableview instead, as long as the listview does not have too many items in it. You can still use a childview with the tableview in much the same way as the listview, you just won't be able to databind it in the same way as you can with a listview, and the items won't recycle either.
Since the listview is designed to contain more items than can be displayed the height will never exceed the screen size (best case) which is the intent of the control, though I suppose you could force it to be larger that seems generally like a bad idea for a lot of reasons.
I suspect what you should do is either create a custom listview adapter, and based on position in the list create the view you want, this would allow all items to scroll like you want.
Listview with different view types per row
This may or may not work depending on what exactly you are trying to do, otherwise you might just want to add views to a linear view inside a scroll view san's the listview.
It just depends on the use case (how many items in the list view, memory issues etc) and what the purpose of the other views are.
Related
I know how to populate a ListView or any other list types, but now I am facing an issue where I should implement a ListView in a ScrollView. So, I decided to use a LinearLayout ( myLinearLayout.addView( adapter.getView(position, null, null) ). As you can see, I am retrieving data from adapter and adding as a new view to my LinearLayout. Everything is working, but if the list is being populated with 30+ rows the application freezes. Each row contains an ImageView and this way the virtual machine can't allocate enough memory.
How I should recycle linearlayout rows?
It doesn't look like a good idea to put a listview inside a scrollview. How are your users gonna use that ? Which gesture will scroll the scrollview and which one will scroll the listview ? It's not going to be usable.
Android components are well designed, you should really consider sticking to a listview that every one knows how to use and is pretty well optimized.
If you have troubles displaying many images in a list, refer this docs from google.
Once you populate the row into a linear layout the views aren't recycled by the adapter. As you wrote its also not possible to have to scroll components one inside the other. Why do you need to show list inside scroll? Did you considered populate the list "on top" of the scroll view? For example in a different fragment?
I have an activity which shows these three things in order.
ViewFlipper (User can fling it left/right)
EditText
ListView (List view can have n number of rows. lets limit it for 100. each row has images which get downloaded asynchronously)
I want that user can scroll vertically so I put above three item in single relative layout and that in to scrollView
<RelativeLayout>
<ScrollView>
<RelativeLayout>
</RelativeLayout>
</ScrollView>
</RelativeLayout>
Problem with this approach
ListView and scroll view together is bad user-experience. When List will cover all screen user will have problem in scrolling complete view itself.
Solution which I could think of
Disable Scroll on ListView and let it show all items (Is this good enough)
User addHeaderView (not sure how to use it)
Second Approach (Which I did and ran into problems).
Instead of using ListView add LinearLayout (replacement of listrow) dynamically.
Problem with this approach
Lot of ugly coding as there is no sophisticated adapter for such scenarios. Need to populate each LinearLayout and it creates more issue because I have async Image loading for every LinearLayout.
What could be better approach. Any alternates?
Do not use a ScrollView and a ListView together, this is a bad thing as mentioned by Romain Guy, the creator of ListView. The problem with you LinearLayout approach is performance: you will need to create n new Views, while the ListView just reuses existing ones.
The solution I could think of (in case it is not possible to make your Layout components to fit on the screen without scrolling), you could disable scrolling in your ListView and add "scroll up" and "scroll down" buttons, setting the onClickListener and OnLongClickListener to let the user control scrolling speed. Though this might be not the best approach. Consider re-disigning your layout so the components fit on a single screen. This is usually not a good user expierince to enable scrolling because of layout components not fitting on a single screen. Your could add a page more to your ViewFlipper and place your ListView there for example
So I have this:
...<!--Stuff above-->
<ListView
android:id="#+id/reminders_list"
android:layout_width="match_parent"
android:layout_height="wrap_content"></ListView>
...<!--More stuff below-->
My problem is when I try to add more rows it does not work because the adapter doesn't add more views if there is no more space. At least in this instance. This means I need to resize it dynamically. Question is how to do this? If something besides resizing is possible I would rather do that. Thanks in advance.
Problem is with your android:layout_height="wrap_content"
Setting height as wrap_content will shows only first three rows rest will be ignored. Try to make it as android:layout_height="fill_parent"
As Romain Guy (Google Engineer workd on UI toolkit) Said in his post
By setting the width to wrap_contentyou are telling ListView to be as wide as the widest of its children. ListView must therefore measure its items and to get the items it has to call getView() on the Adapter. This may happen several times depending on the number of layout passes, the behavior of the parent layout, etc.
So if you set the layout width or layout height of your ListView to wrap_content the ListView will try to measure every single view that is attached to it - which is definitely not what you want.
Keep in mind: avoid setting wrap_content for ListViews or GridViews at all times, for more details see this Google I/O video talking about the world of listview
Dynamically Adding rows to List View Link_1
Dynamically Adding rows to List View Link_2
Dynamically Adding rows to List View Link_3
Dynamically Adding rows to List View Link_4
When adding elements to the List Adapter, you need to call its notifyDataSetChanged() member function to which notifies any attached observers (such as a ListView), that the data has changed, and will cause it to refresh.
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....
I'm making a GUI with two different parts. The first part (at the top) is composed of some banners, several fixed buttons. So I think using LinearLayout is the most straightforward way to implement. The second part is composed of several similar items grouped together which can be implemented by using ExpandableListView, I think.
However the problem is that the content exceeds the screen size. So I intend to put two of them into a ScrollView. I checked several sources, it seems that putting "ExpandableListView" inside a ScroolView is NOT possible, or not efficent, so I'm afraid...
Would you help to confirm if this is possible? efficient ?
If no, would you give me some recommendations for this layout design?
I'm indeed looking forward to your supports.
Sincerely.
If you have a fixed header at the top of a list, use ListView's header view feature.
Putting ListViews in ScrollViews fundamentally makes no sense and here is why:
ListView has one purpose: to efficiently display unbounded data sets. Since these can be extremely large (tens of thousands of items and more) you do not want to create a View for each item up front. Instead, ListView asks its Adapter for Views only for the items that currently fit in the ListView's measured space on screen. When an item's View is scrolled out of sight, ListView disconnects that View and hands it back to the adapter to fill out with new data and reuse to show other items. (This is the convertView parameter to an Adapter's getView method.)
ScrollView also has one purpose: to take a single child view and give it "infinite" vertical space to fit within. The user can then scroll up and down to see the full content.
Now given this, how many item Views would a ListView create for a 100,000 item Adapter if it had infinite height available to fill? :)
By putting a ListView inside a ScrollView you defeat ListView's key purpose. The parent ScrollView will give the ListView effectively infinite height to work with, but ListView wants to have a bounded height so that it can provide a limited window into a large data set.
Well Expandable List View itself has scrollable property by placing it in scroll view is really undesirable.As the both scroll would contradict and smooth scrolling can't be obtained in that case..
If we have any data to be shown prior or later to list...
Best way is to use header and footer view to list...
I recommend you use header and footer in your case.