Vertical LinearLayout with WrapContent width - make children fill it up to widest child

452 Views Asked by At

I want to create vertical LinearLayout with couple of Button children, where each child has width of widest of them.

However depending on using MATCH_PARENT or WRAP_CONTENT for children width, I get either LinearLayout taking whole screen's width, or Buttons not filling LinearLayout. Screenshots below (fill/wrap):

fill example wrap example

Example Activity code:

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    RelativeLayout mainView = new RelativeLayout(this);
    mainView.setBackgroundColor(Colors.WHITE);

    String[] buttonsNames = new String[] { "Short", "Looooooong", "Medium" };
    View buttonsView = getButtonsView(buttonsNames);

    mainView.addView(buttonsView, new RelativeLayout.LayoutParams(
            RelativeLayout.LayoutParams.WRAP_CONTENT,
            RelativeLayout.LayoutParams.WRAP_CONTENT));
    setContentView(mainView);
}

private View getButtonsView(String[] buttonNames) {
    LinearLayout buttonsView = new LinearLayout(this);
    buttonsView.setOrientation(LinearLayout.VERTICAL);
    buttonsView.setBackgroundColor(Colors.BLACK);

    for (int i = 0; i < buttonNames.length; i++) {
        Button button = new Button(this);
        button.setText(buttonNames[i]);

        ///////////// HERE LAYS THE PROBLEM //////////

        buttonsView.addView(button, new LinearLayout.LayoutParams(
                LinearLayout.LayoutParams.MATCH_PARENT,
                //LinearLayout.LayoutParams.WRAP_CONTENT, // neither of them works
                LinearLayout.LayoutParams.WRAP_CONTENT));

        View redLineDivider = new View(this);
        redLineDivider.setBackgroundColor(Colors.RED);
        buttonsView.addView(redLineDivider, new LinearLayout.LayoutParams(
                LinearLayout.LayoutParams.MATCH_PARENT, 2));
    }

    return buttonsView;
}

As you can see on second screenshot, red lines actually take whole width without stretching LinearLayout - it is because at least one view has set width.

Potential fix I have came up with is to find widest button (with longest text) and make it use WRAP_CONTENT, while all the rest use MATCH_PARENT, which gives me expected result:

wanted result

Code:

buttonsView.addView(button, new LinearLayout.LayoutParams(
                isLongestText(i) ? LinearLayout.LayoutParams.WRAP_CONTENT
                        : LinearLayout.LayoutParams.FILL_PARENT,
                LinearLayout.LayoutParams.WRAP_CONTENT));

It doesn't feel like elegant solution though - is there any intended mechanism for situation like this, that I am missing out?

1

There are 1 best solutions below

0
On

Following is the trick:

  1. Mention the width of the LinearLayout containing the buttons (buttonsView in your code) as WRAP_CONTENT.
  2. Mention the width of each button as MATCH_PARENT

Your program should give you the expected result if you do not include the redLineDivider View. There seems to be some issue with setting the width of redLineDivider. As an alternative you can declare it as a LinearLayout to make your code work perfectly.

// View redLineDivider = new View(this);
// Instead declare it as a LinearLayout
LinearLayout redLineDivider = new LinearLayout(this);

Hope this will be useful.