9

I have an XML definition for a view that I am adding to a larger container view with addChild. It's based on a LinearLayout and looks basically like this:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="52dip"
android:background="@drawable/box_bg"
android:clickable="true"
android:onClick="onTreeBoxClick"
android:orientation="horizontal" >

<ImageView android:id="@+id/box_photo"
    android:layout_width="45dip"
    android:layout_height="45dip"
        ...
/>
<RelativeLayout
    android:layout_width="0dip"
    android:layout_weight="1"
    android:layout_height="wrap_content"
>

(Remainder omitted -- probably not relevant since it's basically working as designed)

When I create these views, I have found the following behaviors that seem odd to me:

  1. Right after I inflate the view, getLayoutParameters() returns null.

  2. After I call addChild() to add it to its parent, getLayoutParameters() returns a valid object.

  3. Examining the LayoutParameters, I find both width and height set to -2 (WRAP_CONTENT), which is clearly not what I specified in the XML file.

  4. When I look at the layout parameters of the enclosed ImageView, it reads out at the specified values.

Can anyone explain what is going on here? Why isn't my specified height being noticed?

This isn't really affecting me since the parent view is a custom view wherein I force the final dimensions of the children with MeasureSpec etc., but I'd like to understand this anyway!

user
  • 86,916
  • 18
  • 197
  • 190
gordonwd
  • 4,537
  • 9
  • 37
  • 53

1 Answers1

25

You didn't provide some details which are important.

1) Right after I inflate the view, getLayoutParameters() returns null.

I would assume that you used this:

inflater.inflate(R.layout.content, null);

in this case the LayoutInflater can't make(at all) proper LayoutParams for the root Linearlayout because it doesn't know who is going to be its parent(so it can create the right type of LayoutParams). If you would use this:

inflater.inflate(R.layout.content, someOtherLayout, false/true);

then the root LinearLayout will have proper LayoutParams because it will see the type of someOtherLayout and create the LayoutParams from this information. You may want to provide a snippet of code to get a better answer if this is not what you currently do.

2) After I call addChild() to add it to its parent, getLayoutParameters() returns a valid object.

I assume that you speak about the addView() method. The addView() method will check the LayoutParams of the view which is trying to add and if those LayoutParams are null then it will automatically assign that view a LayoutParams object returned by its generateDefaultLayoutParams() method.

3) Examining the LayoutParameters, I find both width and height set to -2 (WRAP_CONTENT), which is clearly not what I specified in the XML file.

As I said at 2, the generated LayoutParams are coming from the generateDefaultLayoutParams() method which will return a LayoutParams instance as the parent was designed to do. For example, a LinearLayout with orientation HORIZONTAL(the default one) will return a LayoutParams instance with width/height set to WRAP_CONTENT.

4) When I look at the layout parameters of the enclosed ImageView, it reads out at the specified values.

Because the LayoutInflater took care of this, as the ImageView it's in the interior of the layout and has a known parent from which the LayoutInflater can make the proper LayoutParams.

user
  • 86,916
  • 18
  • 197
  • 190
  • Thanks. I eventually figured out how this works. What I did to fix it was to use the 3rd argument of addView() to specify the desired LayoutParams for the view being added. (And yes, I mistyped addView as addChild in my OP, thinking of the inverse of getChild() that I call in my custom view class.:-) ) – gordonwd Dec 21 '12 at 20:16
  • when inflating with parent, you should use false as the third parameter. true did not work for me, params were still false. In short, do inflater.inflate(R.layout.content, someOtherLayout, false); – JoachimR Mar 31 '14 at 14:05