2

I add buttons while runtime to a LinearLayout (vertical orientation) ...

private void addButtons(String[] titles) {
    for (String title : titles) {
        Button button = ButtonBuilder.getButton(getActivity());
        button.setText(title);
        mButtonsLayout.addView(button);
    }
}

Each button has a style defined in XML.

<!-- styles.xml -->
<style name="Button">
    <item name="android:layout_width">match_parent</item>
    <item name="android:layout_height">wrap_content</item>
    <item name="android:gravity">center</item>
    <item name="android:layout_margin">8dp</item>
</style>

Although I defined a layout_margin all buttons sit next to each other without any spacing. How can I add margin space between them?


As suggested by nmw I am trying to introduce the parent layout to the inflater.

private void addButtons(String[] titles) {
    for (String title : titles) {
        Button button = ButtonBuilder.getButton(getActivity(), mButtonsLayout);
        button.setText(title);
        mButtonsLayout.addView(button);
    }
}

..

// ButtonBuilder.java
public static Button getButton(Activity activity, ViewGroup parent) {
    return (Button)activity.getLayoutInflater().inflate(R.layout.custom_button, 
                                                        parent);
}

This results in an exception ..

java.lang.ClassCastException: android.widget.LinearLayout cannot be \
   cast to android.widget.Button
JJD
  • 50,076
  • 60
  • 203
  • 339

3 Answers3

5

layout_margin will be ignored when the layout is inflated due to there being no parent ViewGroup at instantiation time. The framework can't create layout params because it doesn't know the parent ViewGroup type.

To fix this you can either:

1/ create the layout params programmatically too, just before adding the View, you can set the margin in those.

or

2/ add a ViewGroup parameter to the getButton builder and pass in mButtonsLayout. Then when you inflate the XML use that as the parent ViewGroup (last parameter on inflate()).

When using method 2/ inflate() will return the ViewGroup not the View (Button in your case), so you'll need to get the Button out of the ViewGroup by using parent.getChildAt(parent.getChildCount()-1).

See the LayoutInflater docs for inflate.


EDIT:

Please mind that the Builder will no longer work as a getButton() method. When using the ViewGroup parameter, the buttons is immediately added to the parent view.

public static Button addButton(Activity activity, ViewGroup parent) {
    activity.getLayoutInflater().inflate(R.layout.custom_button, parent);
    return (Button) parent.getChildAt(parent.getChildCount() - 1);
}

Therefore, you can no longer add the view in your main class.

// mButtonsLayout.addView(button); // Remove this

This will otherwise cause the following error:

java.lang.IllegalStateException: The specified child already has a parent. \
    You must call removeView() on the child's parent first.
JJD
  • 50,076
  • 60
  • 203
  • 339
nmw
  • 6,664
  • 3
  • 31
  • 32
0

Try something like this:

FrameLayout.LayoutParams layoutParams = 
   new FrameLayout.LayoutParams(LayoutParams.WRAP_CONTENT, 
                                 LayoutParams.WRAP_CONTENT);
layoutParams.setMargins(0, 0, 0, 0);
mButtonsLayout.setLayoutParams(layoutParams);
lokoko
  • 5,785
  • 5
  • 35
  • 68
  • This results in `java.lang.ClassCastException: android.widget.LinearLayout$LayoutParams cannot be cast to android.widget.FrameLayout$LayoutParams`. – JJD Feb 28 '13 at 17:38
0

use this to send margin dynamically

MarginLayoutParams marginParams = new MarginLayoutParams(backToMainScreenImageView.getLayoutParams());
marginParams.setMargins(0, 0, (int) UIUtil.getRadialButtonMainMargin(this), 0);
LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(marginParams);
backToMainScreenImageView.setLayoutParams(layoutParams);
DjHacktorReborn
  • 2,908
  • 2
  • 20
  • 29