安卓 LayoutInflater詳解
Android LayoutInflater詳解
在實際開發中LayoutInflater這個類還是非常有用的,它的作用類似於findViewById()。不同點是LayoutInflater是用來找res/layout/下的xml佈局檔案,並且例項化;而findViewById()是找xml佈局檔案下的具體widget控制元件(如Button、TextView等)。
具體作用:
1、對於一個沒有被載入或者想要動態載入的介面,都需要使用LayoutInflater.inflate()來載入;
2、對於一個已經載入的介面,就可以使用Activiyt.findViewById()方法來獲得其中的介面元素。
LayoutInflater 是一個抽象類,在文件中如下宣告:
public abstract class LayoutInflater extends Object
獲得 LayoutInflater 例項的三種方式
- LayoutInflater inflater = getLayoutInflater();//呼叫Activity的getLayoutInflater()
- LayoutInflater inflater = LayoutInflater.from(context);
- LayoutInflater inflater = (LayoutInflater)context.getSystemService
(Context.LAYOUT_INFLATER_SERVICE);
其實,這三種方式本質是相同的,從原始碼中可以看出:
getLayoutInflater():
Activity 的 getLayoutInflater() 方法是呼叫 PhoneWindow 的getLayoutInflater()方法,看一下該原始碼:
public PhoneWindow(Context context)
{
super(context);
mLayoutInflater = LayoutInflater.from(context);
}
可以看出它其實是呼叫 LayoutInflater.from(context)。
LayoutInflater.from(context):
public static LayoutInflater from(Context context)
{
LayoutInflater LayoutInflater = (LayoutInflater) context.getSystemService
(Context.LAYOUT_INFLATER_SERVICE); if (LayoutInflater == null) { throw new AssertionError("LayoutInflater not found."); } return LayoutInflater;
}
可以看出它其實呼叫 context.getSystemService()。
結論:所以這三種方式最終本質是都是呼叫的Context.getSystemService()。
另外getSystemService()是Android很重要的一個API,它是Activity的一個方法,根據傳入的NAME來取得對應的Object,然後轉換成相應的服務物件。以下介紹系統相應的服務。
傳入的Name 返回的物件 說明
WINDOW_SERVICE WindowManager 管理開啟的視窗程式
LAYOUT_INFLATER_SERVICE LayoutInflater 取得xml裡定義的view
ACTIVITY_SERVICE ActivityManager 管理應用程式的系統狀態
POWER_SERVICE PowerManger 電源的服務
ALARM_SERVICE AlarmManager 鬧鐘的服務
NOTIFICATION_SERVICE NotificationManager 狀態列的服務
KEYGUARD_SERVICE KeyguardManager 鍵盤鎖的服務
LOCATION_SERVICE LocationManager 位置的服務,如GPS
SEARCH_SERVICE SearchManager 搜尋的服務
VEBRATOR_SERVICE Vebrator 手機震動的服務
CONNECTIVITY_SERVICE Connectivity 網路連線的服務
WIFI_SERVICE WifiManager Wi-Fi服務
TELEPHONY_SERVICE TeleponyManager 電話服務
inflate 方法
通過 sdk 的 api 文件,可以知道該方法有以下幾種過載形式,返回值均是 View 物件,如下:
public View inflate (int resource, ViewGroup root)
public View inflate (XmlPullParser parser, ViewGroup root)
public View inflate (XmlPullParser parser, ViewGroup root, boolean attachToRoot)
public View inflate (int resource, ViewGroup root, boolean attachToRoot)
示意程式碼:
LayoutInflater inflater = (LayoutInflater)getSystemService(LAYOUT_INFLATER_SERVICE);
View view = inflater.inflate(R.layout.custom, (ViewGroup)findViewById(R.id.test));
//EditText editText = (EditText)findViewById(R.id.content);// error
EditText editText = (EditText)view.findViewById(R.id.content);
對於上面程式碼,指定了第二個引數 ViewGroup root,當然你也可以設定為 null 值。
注意:
·inflate 方法與 findViewById 方法不同;
·inflater 是用來找 res/layout 下的 xml 佈局檔案,並且例項化;
·findViewById() 是找具體 xml 佈局檔案中的具體 widget 控制元件(如:Button、TextView 等)。
LayoutInflater(佈局服務)
本節引言:
本節繼續帶來的是Android系統服務中的LayoutInflater(佈局服務),說到佈局,大家第一時間 可能想起的是寫完一個佈局的xml,然後呼叫Activity的setContentView()載入佈局,然後把他顯示 到螢幕上是吧~其實這個底層走的還是這個LayoutInflater,用的Android內建的Pull解析器來解析 佈局。一般在Android動態載入佈局或者新增控制元件用得較多,本節我們就來學習下他在實際開發中 的一些用法~
1.LayoutInflater的相關介紹
1)Layout是什麼鬼?
答:一個用於載入佈局的系統服務,就是例項化與Layout XML檔案對應的View物件,不能直接使用, 需要通過 getLayoutInflater ( )方法或 getSystemService ( )方法來獲得與當前Context繫結的 LayoutInflater例項!
2)LayoutInflater的用法
①獲取LayoutInflater例項的三種方法:
LayoutInflater inflater1 = LayoutInflater.from(this); LayoutInflater inflater2 = getLayoutInflater(); LayoutInflater inflater3 = (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE);
PS:後面兩個其實底層走的都是第一種方法~
②載入佈局的方法:
public View inflate (int resource, ViewGroup root, boolean attachToRoot) 該方法的三個引數依次為:
①要載入的佈局對應的資源id
②為該佈局的外部再巢狀一層父佈局,如果不需要的話,寫null就可以了!
③是否為載入的佈局檔案的最外層套一層root佈局,不設定該引數的話, 如果root不為null的話,則預設為true 如果root為null的話,attachToRoot就沒有作用了! root不為null,attachToRoot為true的話,會在載入的佈局檔案最外層巢狀一層root佈局; 為false的話,則root失去作用! 簡單理解就是: 是否為載入的佈局新增一個root的外層容器~!
③通過LayoutInflater.LayoutParams來設定相關的屬性:
比如RelativeLayout還可以通過addRule方法新增規則,就是設定位置:是參考父容器呢? 還是參考子控制元件?又或者設定margin等等,這個由你決定~
2.純Java程式碼載入佈局
我們早已習慣了使用XML生成我們需要的佈局,但是在一些特定的情況下,我們 需要使用Java程式碼往我們的佈局中動態的新增元件或者佈局!
但是不建議大家完全地使用Java程式碼來編寫Android頁面佈局,首先一點就是程式碼會多, 一多久容易亂,而且不利於業務的分離,我們還是建議使用xml來完成佈局,然後通過 Java程式碼對裡面的元件進行修改,當然有些時候可能需要使用Java動態的來新增元件!
純Java程式碼載入佈局的流程:
——Step 1:
① 建立容器 :LinearLayout ly = new LinearLayout(this);
② 建立元件 :Button btnOne = new Button(this);
——Step 2:
可以為容器或者元件設定相關屬性: 比如: LinearLayout ,我們可以設定元件的排列方向: ly.setOrientation(LinearLayout.VERTICAL); 而元件也可以:比如Button: btnOne.setText(“按鈕1″); 關於設定屬性的方法可參見Android 的API,通常xml設定的屬性只需在前面新增:set即可,比如 setPadding (左,上,右,下);
——Step 3:
將元件或容器新增到容器中,這個時候我們可能需要設定下元件的新增位置,或者設定他的大小: 我們需要用到一個類:LayoutParams,我們可以把它看成佈局容器的一個資訊包!封裝位置與大小 等資訊的一個類!先演示下設定大小的方法:(前面的LinearLayout可以根據不同容器進行更改)
LinearLayout.LayoutParams lp1 = new LinearLayout.LayoutParams( LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
很簡單,接著就到這個設定位置了,設定位置的話,通常我們考慮的只是RelativeLayout! 這個時候用到LayoutParams的addRule( )方法!可以新增多個addRule( )哦! 設定元件在父容器中的位置,
比如設定元件的對其方式:
RelativeLayout rly = new RelativeLayout(this); RelativeLayout.LayoutParams lp2 = new RelativeLayout.LayoutParams( LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT); lp2.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM); Button btnOne = new Button(this); rly.addView(btnOne, lp2);
參照其他元件的對其方式: (有個缺點,就是要為參考元件手動設定一個id,是 手動 !!!!) 比如:設定btnOne居中後,讓BtnTwo位於btnOne的下方以及父容器的右邊!
public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); RelativeLayout rly = new RelativeLayout(this); Button btnOne = new Button(this); btnOne.setText("按鈕1"); Button btnTwo = new Button(this); btnTwo.setText("按鈕2"); // 為按鈕1設定一個id值 btnOne.setId(123); // 設定按鈕1的位置,在父容器中居中 RelativeLayout.LayoutParams rlp1 = new RelativeLayout.LayoutParams( LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT); rlp1.addRule(RelativeLayout.CENTER_IN_PARENT); // 設定按鈕2的位置,在按鈕1的下方,並且對齊父容器右面 RelativeLayout.LayoutParams rlp2 = new RelativeLayout.LayoutParams( LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT); rlp2.addRule(RelativeLayout.BELOW, 123); rlp2.addRule(RelativeLayout.ALIGN_PARENT_RIGHT); // 將元件新增到外部容器中 rly.addView(btnTwo, rlp2); rly.addView(btnOne, rlp1); // 設定當前檢視載入的View即rly setContentView(rly); } }
——step 4:
呼叫setContentView( )方法載入佈局物件即可! 另外,如果你想移除某個容器中的View,可以呼叫容器. removeView (要移除的元件);
執行截圖:
3.Java程式碼動態新增控制元件或xml佈局
第二點我們講解了使用純Java程式碼來載入佈局,實際當中用得並不多,更多的時候是動態 的新增View控制元件以及動態的載入XML佈局!
1)Java程式碼動態增加View
動態新增元件的寫法有兩種,區別在於是否需要先 setContentView(R.layout.activity_main) ; 下面演示下兩種不同寫法新增一個Button的例子:
先寫個佈局檔案先: activity_main.xml :
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/RelativeLayout1" android:layout_width="match_parent" android:layout_height="match_parent" > <TextView android:id="@+id/txtTitle" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="我是xml檔案載入的佈局"/> </RelativeLayout>
第一種不需要setContentView()載入佈局檔案先:
public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); Button btnOne = new Button(this); btnOne.setText("我是動態新增的按鈕"); RelativeLayout.LayoutParams lp2 = new RelativeLayout.LayoutParams( LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT); lp2.addRule(RelativeLayout.CENTER_IN_PARENT); LayoutInflater inflater = LayoutInflater.from(this); RelativeLayout rly = (RelativeLayout) inflater.inflate( R.layout.activity_main, null) .findViewById(R.id.RelativeLayout1); rly.addView(btnOne,lp2); setContentView(rly); } }
第二種不需要setContentView()載入佈局檔案先:
public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Button btnOne = new Button(this); btnOne.setText("我是動態新增的按鈕"); RelativeLayout.LayoutParams lp2 = new RelativeLayout.LayoutParams( LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT); lp2.addRule(RelativeLayout.CENTER_IN_PARENT); RelativeLayout rly = (RelativeLayout) findViewById(R.id.RelativeLayout1); rly.addView(btnOne,lp2); } }
分析總結:
程式碼很簡單,建立按鈕後,我們又建立了一個LayoutParams物件,用來設定Button的大小, 又通過addRule()方法設定了Button的位置!
第一種方法:通過LayoutInflate的inflate()方法載入了activity_main佈局,獲得了外層容器, 接著addView新增按鈕進容器,最後setContentView();
第二種方法:因為我們已經通過setContetView()方法載入了佈局,此時我們就可以通過 findViewById找到這個外層容器,接著addView,最後setContentView()即可!
另外,關於這個setContentView( )他設定的檢視節點是整個XML的根節點!
2)Java程式碼動態載入xml佈局
接下來的話,我們換一個,這次載入的是xml檔案! 動態地新增xml檔案 ! 先寫下主佈局檔案和動態載入的佈局檔案:
activity_main.xml:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/RelativeLayout1" android:layout_width="match_parent" android:layout_height="match_parent" > <Button android:id="@+id/btnLoad" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="動態載入佈局"/> </RelativeLayout>
inflate.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" android:gravity="center" android:orientation="vertical" android:id="@+id/ly_inflate" > <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="我是Java程式碼載入的佈局" /> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="我是佈局裡的一個小按鈕" /> </LinearLayout>
接著到我們的 MainActivity.java 在這裡動態載入xml佈局:
public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //獲得LayoutInflater物件; final LayoutInflater inflater = LayoutInflater.from(this); //獲得外部容器物件 final RelativeLayout rly = (RelativeLayout) findViewById(R.id.RelativeLayout1); Button btnLoad = (Button) findViewById(R.id.btnLoad); btnLoad.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { //載入要新增的佈局物件 LinearLayout ly = (LinearLayout) inflater.inflate( R.layout.inflate, null, false).findViewById( R.id.ly_inflate); //設定載入佈局的大小與位置 RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams( LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT); lp.addRule(RelativeLayout.CENTER_IN_PARENT); rly.addView(ly,lp); } }); } }
執行截圖:
程式碼分析:
①獲取容器物件:
final RelativeLayout rly = (RelativeLayout) findViewById(R.id.RelativeLayout1);
②獲得Inflater物件,同時載入被新增的佈局的xml,通過findViewById找到最外層的根節點
final LayoutInflater inflater = LayoutInflater.from(this); LinearLayout ly = (LinearLayout) inflater.inflate(R.layout.inflate, null, false) .findViewById(R.id.ly_inflate);
③為這個容器設定大小與位置資訊:
RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams( LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT); lp.addRule(RelativeLayout.CENTER_IN_PARENT);
④新增到外層容器中:
rly.addView(ly,lp);
4.LayoutInflater的inflate()方法原始碼
最後提供下LayoutInflater的inflate()方法的原始碼吧,有興趣的可以看看~,其實就是Pull解析而已~
public View inflate(XmlPullParser parser, ViewGroup root, boolean attachToRoot) { synchronized (mConstructorArgs) { final AttributeSet attrs = Xml.asAttributeSet(parser); mConstructorArgs[0] = mContext; View result = root; try { int type; while ((type = parser.next()) != XmlPullParser.START_TAG && type != XmlPullParser.END_DOCUMENT) { } if (type != XmlPullParser.START_TAG) { throw new InflateException(parser.getPositionDescription() + ": No start tag found!"); } final String name = parser.getName(); if (TAG_MERGE.equals(name)) { if (root == null || !attachToRoot) { throw new InflateException("merge can be used only with a valid " + "ViewGroup root and attachToRoot=true"); } rInflate(parser, root, attrs); } else { View temp = createViewFromTag(name, attrs); ViewGroup.LayoutParams params = null; if (root != null) { params = root.generateLayoutParams(attrs); if (!attachToRoot) { temp.setLayoutParams(params); } } rInflate(parser, temp, attrs); if (root != null && attachToRoot) { root.addView(temp, params); } if (root == null || !attachToRoot) { result = temp; } } } catch (XmlPullParserException e) { InflateException ex = new InflateException(e.getMessage()); ex.initCause(e); throw ex; } catch (IOException e) { InflateException ex = new InflateException( parser.getPositionDescription() + ": " + e.getMessage()); ex.initCause(e); throw ex; } return result; } } 本段來源: http://www.runoob.com/w3cnote/android-tutorial-layoutinflater.html 我們在Android開發中,對於將佈局填充成View物件,最常用的兩種辦法是:View類的方法inflate和LayoutInflater類的inflate方法, 今天有朋友問到這兩種填充方法的區別,就查看了一下兩者的區別,寫成文章,以方便有需要的人。 首先我們要清楚兩者大致的區別,之後我們再來慢慢看兩者具體的不同之處。 LayoutInflater類的inflate方法適用於所有需要進行佈局填充的場景,是Android中專門進行佈局填充的方法,Android中其他需要 使用佈局填充的地方,都會呼叫本方法,而不是View類中的inflate方法。該方法不是靜態方法,需要先建立LayoutInflater類的物件 才能呼叫。 View類中的inflate方法內部包裹了LayoutInflater類的inflate方法,這個方法是一個靜態方法,不需要建立View類的物件,直接使用 View類名呼叫,相比上一種方法是一種簡便方法。但很明顯,這個方法不如上一個方法功能強大。 若是您只想大概瞭解兩者的區別,您讀到這裡已經足夠了,下面的分析較為詳細,請根據您的需要閱讀下面的內容。 現在我們開始慢慢的研究兩者具體的不同之處。 因為LayoutInflater類的inflate方法是所有佈局填充方法的基石,我們先來看看這個方法吧。 我們從Google官方的SDK中的定義入手,得到比較標準的概念。 關於LayoutInflater類 該類是一個抽象類,繼承自Object,存在於android.view包下。接下來我們只看和本文相關的內容, 不會再做過多的擴充套件。 以下是SDK中的敘述: Instantiates a layout XML file into its corresponding View objects. It is never used directly. Instead, use getLayoutInflater() or getSystemService(String) to retrieve a standard LayoutInflater instance that is already hooked up to the current context and correctly configured for the device you are running on. For example: LayoutInflater inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); To create a new LayoutInflater with an additional LayoutInflater.Factory for your own views, you can use cloneInContext(Context) to clone an existing ViewFactory, and then call setFactory(LayoutInflater.Factory) on it to include your Factory. For performance reasons, view inflation relies heavily on pre-processing of XML files that is done at build time. Therefore, it is not currently possible to use LayoutInflater with an XmlPullParser over a plain XML file at runtime; it only works with an XmlPullParser returned from a compiled resource (R.something file.) 翻譯和闡述: LayoutInflater類的作用是,將xml佈局檔案例項化為它對應的View物件。這個類不能直接使用,也就是不能直接呼叫其中的成員。一般,我們通過getLayoutInflater()方法或者 getSystemService(String) 方法來獲得該類的例項,通過以上兩個方法獲得的LayoutInflater類例項,已經和當前的上下文關聯起來,並且已經正確配置在當前程式執行的裝置上。我們順便說一下這兩個獲得例項的方法:getLayoutInflater()方法, 並不是上下文的方法,Activity類有這個方法,不需要傳入引數,在Activity中直接呼叫即可。Fragment類也有這個方法,但是需要傳入一個Bundle物件作為引數。可以看到,通過該方法獲得的LayoutInflater類物件 和上下文環境相配合。getSystemService(String)方法是Context的方法,需要傳入Context的成員變數作為引數,獲得相應的物件,要獲得LayoutInflater物件,需要傳入Context.LAYOUT_INFLATER_SERVICE 以上介紹的LayoutInflater類是Android系統為我們提供的通用類,如果我們想要為我們的View物件建立專用的LayoutInflater類,則可以用到LayoutInflater.Factory ,這是一個LayoutInflater類內部的介面,通過 工廠設計模式可以使我們獲得定製的專用LayoutInflater類。我們可以使用cloneInContext(Context)來克隆一個已經存在的ViewFactory,然後呼叫setFactory(LayoutInflater.Factory)方法,將我們建立好的 工廠包括進來。在這裡我大概說明一下這段話的意思和作用:當我在一個上下文環境中建立好了一個LayoutInflater工廠之後,我們又想在另一個上下文環境中使用這個LayoutInflater工廠,那該怎麼辦?這裡說的一種方法 是,我們在當前上下文環境中,使用LayoutInflater類物件呼叫cloneInContext(Context)方法,其中的引數填寫新上下文物件,因為我們要在新的上下文環境中使用。然後接著呼叫setFactory(LayoutInflater.Factory)方法, 其中的引數就是我們目前建立的LayoutInflater工廠。這樣建立完成後,我們在新上下文環境中,就可以呼叫目前上下文環境中綁定了LayoutInflater工廠的LayoutInflater類物件了。關於這裡的更詳細用法在本文中就不更多闡述了,有興趣的朋友請參看我的另一篇文章。 xml檔案在建立階段的前處理過程嚴重影響View物件填充階段的效能(進而影響整體軟體的效能),這是因為inflate方法內部使用的pull解析,若是xml檔案在進行填充之前已經被xml解析了,那麼inflate方法在使用時就非常輕鬆,否則會非常困難。因此,我們不會使用LayoutInflater類處理普通的xml檔案,而是用來處理已經編譯的xml檔案,例如R.··········,這樣的xml檔案會返回一個已經解析了xml檔案的pull解析器,而普通的xml檔案返回的解析器則不然。更詳細的內容請參看我的另一篇文章。 好啦,通過以上介紹,我們大概對LayoutInflater類有了一個大概瞭解,之後我們來看以下這個類中的4個過載的inflate方法應該如何使用。 這4個方法中,有兩個是通過XmlPullParser作為資料來源建立view物件,剩下兩個就是我們平時常用的兩個通過resource目錄下的檔案作為資料來源的方法。 前兩個方法在此我們不做詳細介紹,這兩個方法我們平時工作根本不會用,但是Android原始檔中則大量使用,後邊我們詳細介紹的方法內部就是用前兩種實現的。今後我會在其他文章中細細的分析這兩個方法的使用,希望能幫助到感興趣的朋友。 接下來我們就看看下邊兩個常用方法的使用。 三個引數的方法 public View inflate (int resource, ViewGroup root, boolean attachToRoot) Inflate a new view hierarchy from the specified xml resource. Throws InflateException if there is an error. 從指定的xml檔案生成新的view檢視關係。出現錯誤時,丟擲InflateException異常。 引數分析 第一個引數,就是我們要填充的xml檔案 第二個引數,這個要和第三個引數有關係,大家慢慢看。若是第三個引數為true,那麼第二個引數的意義是,從第一個引數填充成的view物件的父控制元件;若是第三個引數為false,那麼第二個引數的意義是, 可以為第一個引數生成的view物件的根佈局提供一系LayoutParams引數的控制元件。 第三個引數,從第一個引數填充成的view物件是否要附著到第二個引數指定的空間上作為子控制元件。 說明:第一個引數不需多說,我們一般就從resource目錄下找到我們要填充的佈局檔案即可,切不可用普通的xml檔案進行填充,除非我們自己做好了相應的xmlpullparser。 若第二個引數為null,也就是我們不指定父控制元件,那麼新生產的view物件的根佈局的某些引數會失效,比如Layout_width和Layout_height會失效,這個大家可以做實驗嘗試,無論第三個引數是什麼。 關於該方法的使用只介紹到這裡,更詳細的用法請查詢專門講解該方法的文章。 返回:若提供了root,且第三個引數為true,則返回root作為根佈局,否則,返回填充出的view物件的根佈局作為根佈局。 兩個引數的用法 public View inflate (int resource, ViewGroup root) 從指定的xml檔案生成新的view檢視關係。出現錯誤時,丟擲InflateException異常。 引數分析: 第一個引數,要填充的xml檔案。 第二個引數,生成的view物件的父控制元件。同樣該引數可以為null。若提供了root,則返回root作為根佈局,否則,返回填充出的view物件的根佈局作為根佈局。 該方法內部呼叫了三個引數的方法,請看下面原始碼: public View inflate(@LayoutRes int resource, @Nullable ViewGroup root) { return inflate(resource, root, root != null); } 兩個引數方法的使用完全和三個引數方法相對應,在此不做更多介紹。 關於View類的inflate方法 public static View inflate (Context context, int resource, ViewGroup root) Inflate a view from an XML resource. This convenience method wraps the LayoutInflater class, which provides a full range of options for view inflation. 將一個xml資源填充成一個view物件。這個簡便的方法包裹了LayoutInflater類,後者提供了view物件填充的所有方法。 引數分析: 第一個引數,上下文 第二個引數,要填充的xml資源 第三個引數,填充成的view物件的根佈局 說明,從SDK解釋中的“convenience”一詞中,我們就可以看到View類中inflate的主要特點,就是簡便。它將LayoutInflater類封裝,且是一個靜態方法,便於呼叫。 以下為原始碼: public static View inflate(Context context, @LayoutRes int resource, ViewGroup root) { LayoutInflater factory = LayoutInflater.from(context); return factory.inflate(resource, root); } 可以看到其內部也就是呼叫了LayoutInflater兩個引數的inflate方法而已,已經在上面介紹過了,不再贅述。 好啦,那我們總結一下吧: LayoutInflater類的inflate方法適用於所有需要進行佈局填充的場景,是Android中專門進行佈局填充的方法,Android中其他需要 使用佈局填充的地方,都會呼叫本方法,而不是View類中的inflate方法。該方法不是靜態方法,需要先建立LayoutInflater類的物件 才能呼叫。 View類中的inflate方法內部包裹了LayoutInflater類的inflate方法,這個方法是一個靜態方法,不需要建立View類的物件,直接使用 View類名呼叫,相比上一種方法是一種簡便方法。但很明顯,這個方法不如上一個方法功能強大。