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

Amo*_*kar 4 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
Run Code Online (Sandbox Code Playgroud)

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

这是我的代码:

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   -->  
Run Code Online (Sandbox Code Playgroud)

Luk*_*rog 12

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

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

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

在第一种情况下,膨胀的布局文件(R.layout.childitemlayout)的根将不会有任何LayoutParams设置(该inflate方法没有分配任何因为第二个参数是null,它不知道LayoutParams要生成哪种类型),所以你修复宽度/高度值丢失.后来,当你做mainLayout.addView(childLayout);mainLayout会检查LayoutParamschildLayout,看看那些是null,将自动设置的一个实例LayoutParams(使用它的generateDefaultLayoutParams()方法).在水平的特定情况下,此方法LinearLayout将返回LayoutParams宽度/高度将设置为的实例WRAP_CONTENT.因此,您的结果childLayoutWRAP_CONTENT以其大小而不是您在其上设置的固定值结束.

在第二种情况下,该inflate方法看到你所建议的LinearLayout mainLayout作为ViewGroup用于生成LayoutParams.这意味着从布局文件中检索到的固定值(用于宽度/高度)可以存储在适当的实例中LayoutParams.当你这样做时mainLayout.addView(childLayout);,mainLayout会看到它childLayout 有正确的LayoutParams实例(它具有布局文件中使用的值)并且不会调用它generateDefaultLayoutParams().