9

我有一个视图的 XML 定义,我使用 addChild 添加到更大的容器视图中。它基于 aLinearLayout并且看起来基本上像这样:

<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"
>

(剩余部分省略——可能不相关,因为它基本上按设计工作)

当我创建这些视图时,我发现以下对我来说似乎很奇怪的行为:

  1. 在我膨胀视图之后,getLayoutParameters() 返回 null。

  2. 在我调用 addChild() 将其添加到其父级后, getLayoutParameters() 返回一个有效对象。

  3. 检查 LayoutParameters,我发现宽度和高度都设置为 -2 (WRAP_CONTENT),这显然不是我在 XML 文件中指定的。

  4. 当我查看随附的 ImageView 的布局参数时,它以指定的值读出。

谁能解释这里发生了什么?为什么没有注意到我指定的高度?

这并没有真正影响到我,因为父视图是一个自定义视图,其中我使用 MeasureSpec 等强制子级的最终尺寸,但我还是想理解这一点!

4

1 回答 1

25

你没有提供一些重要的细节。

1) 在我膨胀视图之后,getLayoutParameters() 返回 null。

我假设你使用了这个:

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

在这种情况下,LayoutInflater不能使(根本)适合LayoutParamsLinearlayout,因为它不知道谁将成为其父级(因此它可以创建正确的类型LayoutParams)。如果你会使用这个:

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

然后根LinearLayout将具有正确的LayoutParams,因为它会看到类型someOtherLayoutLayoutParams从这些信息中创建。如果这不是您当前所做的,您可能需要提供一段代码以获得更好的答案。

2) 在我调用 addChild() 将其添加到其父级后, getLayoutParameters() 返回一个有效对象。

我假设您谈论的是addView()方法。该addView()方法将检查LayoutParams试图添加的视图,如果是LayoutParamsnull那么它将自动为该视图分配其方法LayoutParams返回的对象。generateDefaultLayoutParams()

3) 检查 LayoutParameters,我发现宽度和高度都设置为 -2 (WRAP_CONTENT),这显然不是我在 XML 文件中指定的值。

正如我在 2 中所说,生成LayoutParams的来自generateDefaultLayoutParams()方法,该方法将返回一个LayoutParams实例,就像父级设计的那样。例如,LinearLayout带有方向HORIZONTAL的(默认方向)将返回一个LayoutParams宽度/高度设置为的实例WRAP_CONTENT

4)当我查看随附的 ImageView 的布局参数时,它以指定的值读出。

因为它LayoutInflater处理了这一点,因为ImageView它位于布局的内部并且有一个已知的父级,LayoutInflater可以从中生成正确的LayoutParams.

于 2012-12-21T20:01:19.370 回答