I've searched around for solutions to this problem, and the only answer I can find seems to be "don't put a ListView into a ScrollView". I have yet to see any real explanation for why though. The only reason I can seem to find is that Google doesn't think you should want to do that. Well I do, so I did.
So the question is, how can you place a ListView into a ScrollView without it collapsing to its minimum height?
ListView is actually already capable of measuring itself to be tall enough to display all items, but it doesn't do this when you simply specify wrap_content (MeasureSpec.UNSPECIFIED). It will do this when given a height with MeasureSpec.AT_MOST. With this knowledge, you can create a very simple subclass to solve this problem which works far better than any of the solutions posted above. You should still use wrap_content with this subclass.
Manipulating the heightMeasureSpec to be AT_MOST with a very large size (Integer.MAX_VALUE >> 4) causes the ListView to measure all of its children up to the given (very large) height and set its height accordingly.
This works better than the other solutions for a few reasons:
On the downside, you could argue that doing this is relying on undocumented behavior in the SDK which could change. On the other hand, you could argue that this is how wrap_content should really work with ListView and that the current wrap_content behavior is just broken.
If you're worried that the behavior could change in the future, you should simply copy the onMeasure function and related functions out of ListView.java and into your own subclass, then make the AT_MOST path through onMeasure run for UNSPECIFIED as well.
By the way, I believe that this is a perfectly valid approach when you are working with small numbers of list items. It may be inefficient when compared to LinearLayout, but when the number of items is small, using LinearLayout is unnecessary optimization and therefore unnecessary complexity.
Here is small modification on @djunod's answer that I need to make it work perfectly:
Here's my solution. I'm fairly new to the Android platform, and I'm sure this is a bit hackish, especially in the part about calling .measure directly, and setting the
LayoutParams.height
property directly, but it works.All you have to do is call
Utility.setListViewHeightBasedOnChildren(yourListView)
and it will be resized to exactly accommodate the height of its items.thanks to Vinay's code here is my code for when you can't have a listview inside a scrollview yet you need something like that
the relativeLayout stays inside a ScrollView so it all becomes scrollable :)
Before it was not possible. But with the release of new Appcompat libraries and Design libraries, this can be achieved.
You just have to use NestedScrollView https://developer.android.com/reference/android/support/v4/widget/NestedScrollView.html
I am not aware it will work with Listview or not but works with RecyclerView.
Code Snippet:
There are plenty of situations where it makes a lot of sense to have ListView's in a ScrollView.
Here's code based on DougW's suggestion... works in a fragment, takes less memory.
call setListViewHeightBasedOnChildren(listview) on each embedded listview.