Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unexpected LayoutParams with an inflated LinearLayout

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!

like image 206
gordonwd Avatar asked Dec 21 '12 18:12

gordonwd


1 Answers

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.

like image 185
user Avatar answered Nov 02 '22 12:11

user