使用LayoutInflator的inflate方法时会有不同的结果

时间:2013-01-15 11:27:39

标签: android android-layout layout-inflater

我想知道LayoutParams如何在LayoutInflator上运作。以下是什么区别:

LinearLayout childLayout=(LinearLayout)inflater.inflate(R.layout.childitemlayout, null); //FIRST WAY
LinearLayout childLayout=(LinearLayout)inflater.inflate(R.layout.childitemlayout, container,false); //SECOND WAY

因为,这两种方法都给我不同的结果。 实际上第二次充气方法给了我两个子布局改变的正确结果,但是第一种方法会给我不同的结果。

这是我的代码:

MainActivity.Java

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        LinearLayout mainLayout=(LinearLayout)findViewById(R.id.mainLayout);
        LayoutInflater inflater=LayoutInflater.from(getApplicationContext());
        for(int i=0;i<10;i++){
            LinearLayout childLayout=(LinearLayout)inflater.inflate(R.layout.childitemlayout, null); //First WAY
//          LinearLayout childLayout=(LinearLayout)inflater.inflate(R.layout.childitemlayout, mainLayout,false);  //SECOND WAY
            mainLayout.addView(childLayout);
        }
    }


main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/mainLayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="horizontal" >

</LinearLayout>


childitemlayout.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="80dp"
    android:layout_height="80dp"
    android:orientation="vertical" 
    android:background="#525f67">

    <TextView android:id="@+id/btn"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:text="Button"
            android:gravity="center"
            />


</LinearLayout>  <!-- Both ways gives different result  --> 


<!-- 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:orientation="vertical" 
    android:background="#525f67">

    <TextView android:id="@+id/btn"
            android:layout_width="80dp"
            android:layout_height="80dp"
            android:text="Button"
            android:gravity="center"
            />


</LinearLayout> Both method gives SAME result   -->  

1 个答案:

答案 0 :(得分:12)

两个inflate()方法之间的主要区别是第二个参数(ViewGroup参数)及其用于为膨胀的布局文件的根视图设置正确的LayoutParams。这很重要,因为LayoutParams保留了视图的各种布局属性(如宽度,高度,定位规则等),并且是必需的,因此该视图的父级可以正确显示视图。

第一种方法基本上说:从这个布局文件构建层次结构视图,但不要将LayoutParams分配给膨胀层次结构的根(可能因为父级还不知道),不要将膨胀的视图附加到父

第二个inflate方法说:从此布局文件构建层次结构视图,还将适当的LayoutParams(基于给予inflate方法的第二个参数)分配给根目录。膨胀的层次结构,也不要将膨胀的视图附加到父

在第一种情况下,膨胀的布局文件(R.layout.childitemlayout)的根将不会设置任何LayoutParamsinflate方法没有分配任何因为第二个参数是null,它不知道要生成哪种类型的LayoutParams,因此您的固定宽度/高度值会丢失。稍后当您mainLayout.addView(childLayout);时,mainLayout会检查LayoutParams的{​​{1}},看看它们是childLayout,并会自动设置null(使用其LayoutParams方法)。在水平generateDefaultLayoutParams()的特定情况下,此方法将返回LinearLayout的实例,其中宽度/高度将设置为LayoutParams。因此,WRAP_CONTENT最终会以childLayout作为其大小,而不是您在其上设置的固定值。

在第二种情况下,WRAP_CONTENT方法会看到您将inflate LinearLayout建议为用于生成mainLayout的{​​{1}}。这意味着从布局文件中检索的固定值(用于宽度/高度)可以存储在ViewGroup的适当实例中。当您执行LayoutParams时,LayoutParams会看到mainLayout.addView(childLayout);具有正确的mainLayout实例(其中包含布局文件中使用的值)并且不会调用它childLayout