How to create two views in Android that use 50% height each, unless one is smaller?

Ollie C picture Ollie C · Nov 30, 2010 · Viewed 14.7k times · Source

Imagine a full Android device screen, I want it split in to two sections:

  1. The upper half has text in it, which may be larger than the space available (or not) and so the text will scroll (i.e. TextView inside a ScrollView)
  2. The lower half contains a MapView control.

Looking specifically at some scenarios:

  1. If the text is small, I want the map to take up more space, i.e. more than 50%. So perhaps 20% text, 80% map.
  2. If the text is larger, it only takes up a MAXIMUM of 50% of the screen space, and then scrolls. So 50% map, 50% text.

At the moment I've assigned weights to the two parts, and that isn't too bad, but if the text is small, the map doesn't expand to take the space, and the layout has a wasted gap that the map could usefully use.

I've tried loads of combinations but can't see how to make this happen. It seems to be a common experience for me that I know what I want, but can't see how to get the available views to deliver it. I'm hoping there's a nice easy way to do this.

Please feel free to make me look like a fool and point out the obvious attribute I've missed :-)

======================================================================

As far as I can see there's no way to do this just in declarative XML and it needs doing in the code. I set the text section height to wrap_content, weight to 0 (no resizing), and have the map set to weight=1 (i.e. take up the remaining space). I then check if the text section (in a ScrollView) is taking up too much space and if so, shrink it back. This code would need changing to support a different layout orientation.

private void fixLayoutProportions()
{
    float maxPercentageOfScreenForText = 50/100;
    LinearLayout container = (LinearLayout)findViewById(R.id.container);
    ScrollView eventText = (ScrollView)findViewById(R.id.text_scroller);
    int heightAvailable = container.getHeight();
    int scrollerHeight = eventText.getHeight();
    if ( scrollerHeight>(heightAvailable*maxPercentageOfScreenForText) )      // Text section using too much space
    {
        eventText.getLayoutParams().height = (int)(heightAvailable*maxPercentageOfScreenForText) ;
        eventText.invalidate();
    }
}

Answer

Damian Kołakowski picture Damian Kołakowski · Nov 30, 2010

You can do it by putting everything into LinearLayout and changing following parameters: