2

It looks like android is ignoring layout parameters for ImageButton. When my layout xml defines ImageButtons with the style, layout_weight is considered. However, when I add the button dynamically, the weight is ignored and I have to define LayoutParameters manually.

Styles.xml entry:

<style name="TabbedPanelToolbarControl" parent="android:style/Widget.ImageButton">
    <item name="android:background">@null</item>
    <item name="android:layout_width">wrap_content</item>
    <item name="android:layout_height">wrap_content</item>
    <item name="android:layout_weight">1.0</item>
    <item name="android:paddingTop">5dp</item>
    <item name="android:paddingBottom">5dp</item>
</style>

Layout xml:

...
<LinearLayout
    android:id="@+id/toolbar"
    android:orientation="vertical" >
    <!-- image buttons go here -->
</LinearLayout>
...

Code:

View view = inflater.inflate(R.layout.test, container, false);
LinearLayout mToolbar = (LinearLayout)view.findViewById(R.id.toolbar);

ImageButton ib = new ImageButton(this.getActivity(), null, R.style.TabbedPanelToolbarControl);

ib.setImageDrawable(icon);
ib.setContentDescription(title);

// ignored layout_weight defined in TabbedPanelToolbarControl style
mToolbar.addView(ib);
// need to re-specify layout
mToolbar.addView(ib, new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT, 1.0f));

Anyone knows a way to force reading of the layout_weight from styles.xml when adding buttons dynamically?

Vadym
  • 964
  • 1
  • 13
  • 31

2 Answers2

4

Reading the layout parameters in the constructor does not work. The reason is quite logical -- when you create the ImageButton

new ImageButton(this.getActivity(), null, R.style.TabbedPanelToolbarControl);

This constructor will read the style attributes. However, since it is not inside a LinearLayout (or any other parent) it has no idea which LayoutParams class it must instantiate. Since the generic ViewGroup.LayoutParams does not have a weight attribute, it will be ignored.

When inflating via LayoutInflater the situation is quite different. The relevant code in the LayoutInflater class is this:

final View view = createViewFromTag(parent, name, attrs);
final ViewGroup viewGroup = (ViewGroup) parent;
final ViewGroup.LayoutParams params = viewGroup.generateLayoutParams(attrs);

Since the viewGroup variable is a fully created LinearLayout, it has an overriden generateLayoutParams() to read both weight and gravity.

matiash
  • 54,791
  • 16
  • 125
  • 154
2

You can get layout parameters from style and then add ImageButton using these parameters.

    ...
    TypedArray a = obtainStyledAttributes(R.style.TabbedPanelToolbarControl, 
            new int[] {android.R.attr.layout_width,
            android.R.attr.layout_height,
            android.R.attr.layout_weight});


    int width = a.getInt(0, LayoutParams.WRAP_CONTENT);
    int height = a.getInt(1, LayoutParams.WRAP_CONTENT);
    float weight = a.getFloat(2, 1);

    mToolbar.addView(ib, new LayoutParams(width, height, weight));
olegr
  • 1,999
  • 18
  • 23
  • Nice, it worked. Still strange that weight is not considered. It may have something to do with ViewGroup not having weight parameter and only LinearLayout having it. – Vadym Jun 13 '14 at 23:28
  • @olegr i have similar problem, paddingBottom is not considered in the style. And i am loading the style. do you know why ? – Lena Bru Jun 13 '14 at 23:48
  • @Ardoramor Try to use `ib.setLayoutParams(new LayoutParams(width, height, weight)); mToolbar.addView(ib);` It has a little bit different implementation. I'm not sure but seems it should work. – olegr Jun 13 '14 at 23:58
  • @Lena Bru Strange that it is not considered. Should work without additional efforts. Try to ask question with your code examples. – olegr Jun 14 '14 at 00:05
  • @olegr i did ask the question here is the link http://stackoverflow.com/q/24182411/2136812 – Lena Bru Jun 14 '14 at 00:11