8

I have a horizontal LinearLayout with three views inside it. Each has its layout_width set to 0dp, and different weights set. They all have wrap_content set for the layout_height.

The problem I have is that when one of them wraps, the others no longer fill the full height of the LinearLayout (they have backgrounds, so this looks ugly).

I want to make all of them fill any remaining vertical space in the LinearLayout, while also allowing them to wrap content if needed. Basically, I want them all to have the height of the tallest sibling.

I have tried setting the layout_gravity to "fill" and "fill_vertical", but that does nothing.

Here is an example of the layout:

<LinearLayout
            android:id="@+id/LinearLayout1"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="@android:color/background_dark"
            android:orientation="horizontal" >

            <Button
                android:id="@+id/job"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_gravity="fill"
                android:layout_margin="1dp"
                android:layout_weight="4"
                android:background="@drawable/btn_bkgnd_dark_grey"
                android:drawableLeft="@drawable/icon_plus"
                android:onClick="jobPressed"
                android:padding="5dp"
                android:text="Add to Job fgh dfhfg "
                android:textAppearance="@style/rowitem_notes"
                android:textColor="@android:color/white" />

            <ImageButton
                android:id="@+id/bookmark"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_gravity="fill"
                android:layout_margin="1dp"
                android:layout_weight="2"
                android:background="@drawable/btn_bkgnd_dark_grey"
                android:onClick="bookmarkPressed"
                android:padding="5dp"
                android:src="@drawable/icon_bookmark" />

            <Button
                android:id="@+id/itemDetailsButton"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_gravity="fill"
                android:layout_margin="1dp"
                android:layout_weight="4"
                android:background="@drawable/btn_bkgnd_dark_grey"
                android:drawableRight="@drawable/icon_info"
                android:onClick="itemDetailsPressed"
                android:padding="5dp"
                android:text="Item Details"
                android:textAppearance="@style/rowitem_notes"
                android:textColor="@android:color/white" />

        </LinearLayout>
chubao
  • 5,871
  • 6
  • 39
  • 64
Dylan
  • 2,614
  • 2
  • 18
  • 21
  • Have you tried changing all the view within your layout container to "match_parent"? If not, why not? – MarsAtomic May 09 '13 at 02:05
  • I guess if you set layout_height="match_parent" will result in the Containter(LinearLayout) occupy whole screen. – buptcoder May 09 '13 at 02:08
  • possible duplicate of [Android: How to make all elements inside LinearLayout same size?](http://stackoverflow.com/questions/1177020/android-how-to-make-all-elements-inside-linearlayout-same-size) – Madan Sapkota Jun 05 '15 at 07:08

3 Answers3

18

I have corrected your layout. Use fill_parent instead of wrap content for child views. I have used default android drawables and colors, replace that with your drawables and styles.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/LinearLayout1"
style="@android:style/ButtonBar"
android:layout_width="fill_parent"
android:gravity="center"
android:layout_height="wrap_content"
android:orientation="horizontal" >

<Button
    android:id="@+id/job"
    android:layout_width="0dip"
    android:layout_height="fill_parent"
    android:layout_gravity="center"
    android:layout_margin="2dp"
    android:layout_weight="4"
    android:background="#33B5E5"
    android:drawableLeft="@android:drawable/btn_star"
    android:onClick="jobPressed"
    android:padding="5dp"
    android:text="Add to Job fgh"
    android:textColor="@android:color/white"
    android:textSize="10sp" />

<ImageButton
    android:id="@+id/bookmark"
    android:layout_width="0dip"
    android:layout_height="fill_parent"
    android:layout_gravity="center"
    android:layout_margin="2dp"
    android:layout_weight="1"
    android:background="#33B5E5"
    android:onClick="bookmarkPressed"
    android:padding="5dp"
    android:scaleType="fitCenter"
    android:src="@android:drawable/ic_input_add" />

<Button
    android:id="@+id/itemDetailsButton"
    android:layout_width="0dip"
    android:layout_height="fill_parent"
    android:layout_gravity="center"
    android:layout_margin="2dp"
    android:layout_weight="4"
    android:background="#33B5E5"
    android:drawableRight="@android:drawable/ic_delete"
    android:onClick="itemDetailsPressed"
    android:padding="5dp"
    android:text="Item Details"
    android:textColor="@android:color/white"
    android:textSize="10sp" />

</LinearLayout>
Sujith
  • 7,543
  • 1
  • 28
  • 38
  • Thank you. The container layout I had this in is stopping the view from resizing properly (it is a custom layout), which is why this didn't work. The line wrapped TextView would not resize to match its content and instead cut it off. You solution seems to work in the general case though. – Dylan May 09 '13 at 06:52
  • Yes and No. It is due to a bug in my custom layout measurement code, so is irrelevant to the original question. Your answer is correct. – Dylan May 10 '13 at 00:29
1

You say the following: "Basically, I want them all to have the height of the tallest sibling". Given that you don't know which is going to be the sibling with the tallest height, then you'll have to do it programatically,basically something like this:

  1. First get the height of each of your widgets, like this:

    int height = widget.getHeight();  //with this you know which is the tallest one
    
  2. Then, create a RelativeLayout params in order to set layout_alignTop attribute to the views that must scale accordingly to the tallest view. Clearly align_Top is referring to the id of the tallest view

    RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT);
    layout.setLayoutParams(params);         
    params.addRule(RelativeLayout.ALIGN_TOP,R.id.tallest_widget);
    widget.setLayoutParams(params);
    
  3. That's all, but take into account that in this solution you'll have to do this using RelativeLayout instead of LinearLayout.

I think RelativeLayout is the solution for this because of the flexibility it gives to you, in this case it allows you to align the top of your views accordingly to a reference(i.e: the tallest view).

Emil Adz
  • 40,709
  • 36
  • 140
  • 187
Daniel Conde Marin
  • 7,588
  • 4
  • 35
  • 44
  • I was hoping to find a way to do it using xml. It always feels like a failure of the API when I have to drop back to code for simple things like this. Thank you though, I may have to implement a custom layout to do it like you say. – Dylan May 09 '13 at 03:17
0

In this case, I think you should do like these: At first, all buttons has the background, so I think you should have known the height of all views. Maybe you can do like these, give the LinearyLayout the maxHeight/minHeight or fixed value, then use the layout_height="match_parent" in the subview. Unless you have to adjust the Ui pragmatically in your code.

buptcoder
  • 2,692
  • 19
  • 22
  • The problem with this is on smaller width screens, the text line wraps and gets cut off. – Dylan May 09 '13 at 03:17