views:

424

answers:

3

I am currently trying to use a ListView inside of a ScrollView. I know from what I've read that this is looked down upon, but I'm trying to get the ListView to expand completely by showing all of its rows so there is no need for it to scroll. I've been struggling, however, with how to tell the ListView to completely expand to show all of its rows since it needs a defined height. Does anyone know of a way to calculate the height of a fully expanded ListView before it is drawn?

This problem mainly stems from the fact that you can't put a scrollable view inside of another scrollable view. I am okay with the fact that the ListView won't be able to scroll as long as I can make it expand to show all of its rows. I cannot do this, however, without being able to give it a defined height, which it seems I would need to calculate.

See the url below for a sketch (I'm a new user so I'm not allowed to post one). It shows that my full layout is too big for the "physical" screen and needs to scroll in order to show the rest of the list and buttons at the bottom. I'm trying to get across that the "virtual" screen is too big to fit on one screen even without the ListView there.

http://img51.imageshack.us/img51/7210/screenmockup.png

+1  A: 

You should not place your ListView in a ScrollView. The ListView is already scrollable.

The ListView should expand fully by default, if it is the only thing in the layout.

If it is not the only thing in the layout, and you want the ListView to expand to take up all available space, set the layout_weight on the ListView to 1, where all other layout_weight=0.

<LinearLayout android:layout_width="fill_parent" 
             android:layout_height="fill_parent" orientation="vertical">
  <TextView id="@+id/title" 
             android:layout_width="wrap_content" 
            android:layout_height="wrap_content"/>
  <ListView id="@+id/listView" 
            android:layout_width="fill_parent" 
            android:layout_height="0dp" 
            android:layout_weight="1"/>
</LinearLayout>

Edit: The ListView is really designed to be scrollable...the screen layout you have in your screenshot doesn't really seem like the "android way".

However, if your really want to circumvent that, you could try inflating one of the rows, get its minHeight, and multiply that by the number of items in the ListView adapter.

LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View view = inflater.inflate(R.layout.label_value_row, null, false);
int height = adapter.getCount() * view.getMinHeight();
Mayra
The ListView, however, will not be scrollable if all its rows are showing. My problem is that I need to show more views in the layout than will fit on just one screen. I don't want the ListView to just expand to the screen, I want it to expand to show all of its rows.
Rudy Mutter
The ListView will automatically scroll if there is more content than will fit on the screen. From the ListView API, a ListView is "A view that shows items in a vertically scrolling list." The scrolling is built in. Try it!
Mayra
Even without the ListView, the other views on the screen are too tall to fit so I need the overlaying view to be a ScrollView. I want the ListView to size itself to be tall enough to show all of its rows. I can accomplish this by giving it a set height in its LayoutParams but the list is dynamic so I am trying to figure out a way to calculate this height. See the edit I provided to the question.
Rudy Mutter
So this is true but the data in my ListView is dynamic from a database and the actual height of each row will be variable based on how the text wraps. Would there be anyway after setting the height of the ListView to this estimation to figure out how much less or more the actual height is?And by the way, thank you for your help so far, much appreciated.
Rudy Mutter
You could compare the number of visible children to the number of children in the adapter, that seems like it could get really messy though. Honestly, it sounds like you might be better off with the LinearLayout jqpubliq suggested. The ListView is really designed to scroll...it lazily loads its content, so only the size of the visible components will be determined until you start scrolling. Its not that hard to replicate the click behavior of the ListView.
Mayra
+1  A: 

If you want a ListView which won't scroll couldn't you just use a LinearLayout?

jqpubliq
I'd like to keep the native android look of a list without having to roll my own.
Rudy Mutter
do you mean the highlight states? If so you can use android.R.drawable.list_selector_background to get the same kind of behavior I believe.
jqpubliq
Yes that, as well as the default header and footer functionality, list gradient seperators, and use of the adapter constructs. I could end up trying to make a clone of the ListView by copying all of the built in android styles, but I would like to avoid this if possible.
Rudy Mutter
I was fighting this as well. Your suggestion to just use a LinearLayout hit me like a hammer to the forehead. Works just right and live is simpler now. Thanks!
Jere.Jones
A: 

I ended up overriding onDraw() of the ListView and calculating the average height of the visible rows in the view then estimating the actual height of the list based on how many items are in the adapter. This estimating happens a couple of times until all of the rows are visible.

Rudy Mutter