這里只討論 LayoutInflater1
的 infalte()
方法。
inflate(int resource, ViewGroup root, boolean attachToRoot);
第一個參數xml布局資源索引,第二個參數指的是加載布局的root。
attachToRoot為true,這個布局會被解析並加載在root下面,如果為false,則會依照root去解析該xml並返回view,但是這個view不會被加載到root里。把xml解析了,並依照root的類型給生成的view set一個LayoutParams ,但不將其add到root里。
我們通過看源碼可以發現兩個參數的方法最終調用的也是三個參數的方法,比如:
public View inflate(int resource, ViewGroup root) {
return inflate(resource, root, root != null);
}
然后是前人總結的內容:
- 如果root為null,attachToRoot將失去作用,設置任何值都沒有意義。
- 如果root不為null,attachToRoot設為true,則會給加載的布局文件的指定一個父布局,即root。
- 如果root不為null,attachToRoot設為false,則會將布局文件最外層的所有layout屬性進行設置,當該view被添加到父view當中時,這些layout屬性會自動生效。
- 在不設置attachToRoot參數的情況下,如果root不為null,attachToRoot參數默認為true。
結合實例來理解:
title.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/title_bg">
<Button
android:id="@+id/title_back"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_margin="5dp"
android:background="@drawable/back_bg"
android:text="Back"
android:textColor="#fff"/>
<TextView
android:id="@+id/title_text"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_weight="1"
android:gravity="center"
android:text="Title Text"
android:textColor="#fff"
android:textSize="24sp"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_margin="5dp"
android:background="@drawable/edit_bg"
android:text="Edit"
android:textColor="#fff"/>
</LinearLayout>
TitleLayout.java
package com.example.uicustomviews;
import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.LinearLayout;
import androidx.annotation.Nullable;
public class TitleLayout extends LinearLayout {
public TitleLayout(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
View inflate = LayoutInflater.from(context).inflate(R.layout.title, this);
}
}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.example.uicustomviews.TitleLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</LinearLayout>
MainActivity.java
package com.example.uicustomviews;
import androidx.appcompat.app.ActionBar;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ActionBar actionBar = getSupportActionBar();
if (actionBar != null) {
actionBar.hide();
}
}
}
這個示例的功能是展示動態引入標題欄的功能的,我們觀察上面的 TitleLayout.java
代碼,其傳入的 root 參數是 this,即當前這個類,第三個參數默認是true,觀察運行結果:
而將第三個參數設置為false的話,則加載不出來標題欄:
View inflate = LayoutInflater.from(context).inflate(R.layout.title, this, false);
然后,我們再添加一行代碼:
View inflate = LayoutInflater.from(context).inflate(R.layout.title, this, false);
this.addView(inflate);
這時,我們發現標題欄又可以正常顯示了:
結合這個,我們就不難理解上面的解釋了——attachToRoot為true,這個布局會被解析並加載在root下面,如果為false,則會依照root去解析該xml並返回view,但是這個view不會被加載到root里。把xml解析了,並依照root的類型給生成的view set一個LayoutParams ,但不將其add到root里。
其他的情況以此類推就好。
批注:我覺得 inflate 在英文中有膨脹、擴充的意思,在這里可以解釋為擴充一個布局出來的意思。
參考:https://blog.csdn.net/runstoppable/article/details/90048828