LayoutInflater和inflate方法的用法
阿新 • • 發佈:2019-01-22
在實際開發中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 例項的三種方式:
1. LayoutInflater inflater = getLayoutInflater(); //呼叫Activity的getLayoutInflater()
2. LayoutInflater localinflater =(LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 3. LayoutInflater inflater = LayoutInflater.from(context);
其實,這三種方式本質是相同的,從原始碼中可以看出:
getLayoutInflater():
Activity 的 getLayoutInflater() 方法是呼叫 PhoneWindow 的getLayoutInflater()方法,看一下該原始碼:
可以看出它其實是呼叫 LayoutInflater.from(context)。
結論:所以這三種方式最終本質是都是呼叫的Context.getSystemService()。
inflate 方法
通過 sdk 的 api 文件,可以知道該方法有以下幾種過載形式,返回值均是 View 物件,如下:
public View inflate (int resource, ViewGroup root)
reSource:View的layout的ID
root:如果為null,則將此View作為根,此時既可以應用此View中的其他控制元件了。
如果!null, 則將預設的layout作為View的根。
2:
public View inflate ( XmlPullParser parser, ViewGroup root)
parser:你需要解析xml的解析介面
root:如果null,則將此View作為根,此時既可以應用此View中的其他控制元件了。
如果!null, 則將預設的layout作為View的根。
3:
public View inflate ( XmlPullParser parser, ViewGroup root, boolean attachToRoot)
parser:你需要解析View的xml的解析介面
root:如果null,則將此View作為根,此時既可以應用此View中的其他控制元件了。
如果!null, 則將預設的layout作為View的根。
attachToRoot:
ture:也就將此解析的xml作為View根
fase:則為預設的xml,做為根檢視View
4:
public View inflate (int resource, ViewGroup root, boolean attachToRoot)
resource:View的layout的ID
root:如果null,則將此View作為根,此時既可以應用此View中的其他控制元件了。
如果!null, 則將預設的layout作為View的根。
attachToRoot:
ture:也就將此解析的xml作為View根
fase:則為預設的xml,做為根檢視View
示意程式碼:
同時在此講講讓我去API中去理解這四個函式的原因吧!
在Activity中:
大家是否知道,在setContentView(new MySurfaceView(this))後,此Activity中宣告的View控制元件,
如:TextView 為什麼引用不到layout佈局檔案中的控制元件ID呢!初一看能夠應用到,但是為什麼編譯就報空指標呢!原因:在setContentView(new MySurfaceView(this))後,此時的View變為了根檢視了,雖然能應用到TextView對應的ID,但是我在 MySurfaceView中根本就沒有這個物件,所以就報空指標咯!解決辦法:
View view = LayoutInflater.from(this).inflate(R.layout.passover, null);注:每解析一次都會產生不同的物件
然後你再引用沒問題,使用自如了。
Android中inflate方法的用法
Inflate()作用就是將xml定義的一個佈局找出來,但僅僅是找出來而且隱藏的,沒有找到的同時並顯示功能。而setContentView()將佈局設定成當前螢幕即Activity的內容,可以直接顯示出來。
SetContentView()一旦呼叫, layout就會立刻顯示UI;而inflate只會把Layout形成一個以view類實現成的物件。有需要時再用setContentView(view)顯示出來。
注:Inflate()或可理解為“隱性膨脹”,隱性擺放在view裡,inflate()前只是獲得控制元件,但沒有大小沒有在View裡佔據空間,inflate()後有一定大小,只是出於隱藏狀態。
一般在activity中通過setContentView()將介面顯示出來,但是如果在非activity中如何對控制元件佈局設定操作了,這需LayoutInflater動態載入。
LayoutInflater flater = LayoutInflater.from(this);View view = flater.inflate(R.layout.example, null);
獲取佈局中的控制元件。
button = (Button) view.findViewById(R.id.button);textView = (TextView)view.findViewById(R.id.tview);
接下來結合原始碼說說inflate方法的二種形式:
1.通過 LayoutInflater類的inflate()方法動態載入。兩種獲得LayoutInflater的方法
a. 通過SystemService獲得
LayoutInflater inflater=(LayoutInflater)context.getSystemService(Context.LAYOUT_INFLEATER_SERVICE);
b. 從給定的context中獲取
Public static LayoutInflater from(Context context)
c. 兩者的區別:實際上是一樣的,原始碼
d. 實現程式碼:
第一步,先獲得LayoutInflater物件。
LayoutInflater inflater=context.getSystemService(Context.LAYOUT_INFLEATER_SERVICE);
第二步,呼叫inflate()方法載入佈局資源。
View view=inflater.inflate(int resource, ViewGroup root);
引數1:要載入的xml資原始檔,加載出錯丟擲InflateException異常。
引數2:新生成檢視的父層,可設定為NULL。
第三步,將新生成的View加入到需要的View中,我們可以通過findViewById()方法獲取當前Acitivty中的檢視MyView,然後把新生成的view加入到Myview中。
MyView.add(view, new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT));
注意:需要指定檢視屬性。
也可以呼叫inflater.inflate(int resource, ViewGroup root)方法時直接將檢視加入到父檢視中。
如:inflater.inflate(R.layout.login,MyView);
這種情況不好控制新檢視的長寬。建議使用第一種。
注: LayoutInflater.inflate()將Layout檔案轉換為View,專門供Layout使用的Inflater。雖然Layout也是 View的子類,但在android中如果想將xml中的Layout轉換為View放入.java程式碼中操作,只能通過Inflater,而不能通過 findViewById()。
第二種方法:使用View的靜態方法:
static View inflate(Context context, int resource, ViewGroup root)
引數1:Acitivity或Application的上下文
引數2:指定的xml佈局檔案
引數3:指定父元件。
同樣可以通過:
View view=View.inflate(this,R.layout.*,null);
生成一個新的View,然後呼叫Add方法指定View的屬性並加入的父元件中。
當然也可以使用View.inflate(this,R.layout.*,MyView)直接加入到父元件中。
findViewById有兩種形式 :
R.layout.xx是引用res/layout/xx.xml的佈局檔案(inflate 方法),R.id.xx是引用佈局檔案裡面的元件,元件的id是xx(findViewById方法)。所有的元件id都能用R.id.xx來檢視,但是 元件不在setContentView()裡面的layout中就無法使用,Activity.findViewById()會出現空指標異常
a. activity中的findViewById(int id)
b. View 中的findViewById(int id)
6.不同點是LayoutInflater是用來找layout下xml佈局檔案,並且例項化!而findViewById()是找具體xml下的具體 widget控制元件(如:Button,TextView等)。
Android上還有一個與Inflate()類似功能的方法叫findViewById(),二者有時均可使用,但也有區別,
區別在於:
findViewById()只能找出當前佈局中的元件,即setConentView()的那個layout裡的元件.
如果你的Activity裡用到別的layout,比如對話方塊layout,你還要設定這個layout上的其他元件的內容,你就必須用inflate()方法先將對話方塊的layout找出來,然後再用findViewById()找到它上面的其它元件。例如:
View view1=View.inflate(this,R.layout.dialog_layout,null);
TextViewdialogTV=(TextView)view1.findViewById(R.id.dialog_tv);
dialogTV.setText("abcd");
注:R.id.dialog_tv是在對話方塊layout上的元件,而這時若直接用this.findViewById(R.id.dialog_tv)肯定會報錯。
具體作用:
1、對於一個沒有被載入或者想要動態載入的介面,都需要使用LayoutInflater.inflate()來載入;
2、對於一個已經載入的介面,就可以使用Activiyt.findViewById()方法來獲得其中的介面元素。
LayoutInflater 是一個抽象類,在文件中如下宣告:
public abstract class LayoutInflater extends Object
獲得 LayoutInflater 例項的三種方式:
1. LayoutInflater inflater = getLayoutInflater(); //呼叫Activity的getLayoutInflater()
2. LayoutInflater localinflater =(LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 3. LayoutInflater inflater = LayoutInflater.from(context);
其實,這三種方式本質是相同的,從原始碼中可以看出:
getLayoutInflater():
Activity 的 getLayoutInflater() 方法是呼叫 PhoneWindow 的getLayoutInflater()方法,看一下該原始碼:
public PhoneWindow(Context context) {
super(context);
mLayoutInflater = LayoutInflater.from(context);
}
可以看出它其實是呼叫 LayoutInflater.from(context)。
可以看出它其實呼叫 context.getSystemService()。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()。
inflate 方法
通過 sdk 的 api 文件,可以知道該方法有以下幾種過載形式,返回值均是 View 物件,如下:
1: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)
public View inflate (int resource, ViewGroup root)
reSource:View的layout的ID
root:如果為null,則將此View作為根,此時既可以應用此View中的其他控制元件了。
如果!null, 則將預設的layout作為View的根。
2:
public View inflate ( XmlPullParser parser, ViewGroup root)
parser:你需要解析xml的解析介面
root:如果null,則將此View作為根,此時既可以應用此View中的其他控制元件了。
如果!null, 則將預設的layout作為View的根。
3:
public View inflate ( XmlPullParser parser, ViewGroup root, boolean attachToRoot)
parser:你需要解析View的xml的解析介面
root:如果null,則將此View作為根,此時既可以應用此View中的其他控制元件了。
如果!null, 則將預設的layout作為View的根。
attachToRoot:
ture:也就將此解析的xml作為View根
fase:則為預設的xml,做為根檢視View
4:
public View inflate (int resource, ViewGroup root, boolean attachToRoot)
resource:View的layout的ID
root:如果null,則將此View作為根,此時既可以應用此View中的其他控制元件了。
如果!null, 則將預設的layout作為View的根。
attachToRoot:
ture:也就將此解析的xml作為View根
fase:則為預設的xml,做為根檢視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)
同時在此講講讓我去API中去理解這四個函式的原因吧!
在Activity中:
大家是否知道,在setContentView(new MySurfaceView(this))後,此Activity中宣告的View控制元件,
如:TextView 為什麼引用不到layout佈局檔案中的控制元件ID呢!初一看能夠應用到,但是為什麼編譯就報空指標呢!原因:在setContentView(new MySurfaceView(this))後,此時的View變為了根檢視了,雖然能應用到TextView對應的ID,但是我在 MySurfaceView中根本就沒有這個物件,所以就報空指標咯!解決辦法:
View view = LayoutInflater.from(this).inflate(R.layout.passover, null);注:每解析一次都會產生不同的物件
然後你再引用沒問題,使用自如了。
Android中inflate方法的用法
Inflate()作用就是將xml定義的一個佈局找出來,但僅僅是找出來而且隱藏的,沒有找到的同時並顯示功能。而setContentView()將佈局設定成當前螢幕即Activity的內容,可以直接顯示出來。
SetContentView()一旦呼叫, layout就會立刻顯示UI;而inflate只會把Layout形成一個以view類實現成的物件。有需要時再用setContentView(view)顯示出來。
注:Inflate()或可理解為“隱性膨脹”,隱性擺放在view裡,inflate()前只是獲得控制元件,但沒有大小沒有在View裡佔據空間,inflate()後有一定大小,只是出於隱藏狀態。
一般在activity中通過setContentView()將介面顯示出來,但是如果在非activity中如何對控制元件佈局設定操作了,這需LayoutInflater動態載入。
<TextView
android:id="@+id/tview"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="ATAAW.COM" />
<Button
android:id="@+id/button"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="按鈕" />
在程式中動態載入以上佈局。LayoutInflater flater = LayoutInflater.from(this);View view = flater.inflate(R.layout.example, null);
獲取佈局中的控制元件。
button = (Button) view.findViewById(R.id.button);textView = (TextView)view.findViewById(R.id.tview);
接下來結合原始碼說說inflate方法的二種形式:
1.通過 LayoutInflater類的inflate()方法動態載入。兩種獲得LayoutInflater的方法
a. 通過SystemService獲得
LayoutInflater inflater=(LayoutInflater)context.getSystemService(Context.LAYOUT_INFLEATER_SERVICE);
b. 從給定的context中獲取
Public static LayoutInflater from(Context context)
c. 兩者的區別:實際上是一樣的,原始碼
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;
}
d. 實現程式碼:
第一步,先獲得LayoutInflater物件。
LayoutInflater inflater=context.getSystemService(Context.LAYOUT_INFLEATER_SERVICE);
第二步,呼叫inflate()方法載入佈局資源。
View view=inflater.inflate(int resource, ViewGroup root);
引數1:要載入的xml資原始檔,加載出錯丟擲InflateException異常。
引數2:新生成檢視的父層,可設定為NULL。
第三步,將新生成的View加入到需要的View中,我們可以通過findViewById()方法獲取當前Acitivty中的檢視MyView,然後把新生成的view加入到Myview中。
MyView.add(view, new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT));
注意:需要指定檢視屬性。
也可以呼叫inflater.inflate(int resource, ViewGroup root)方法時直接將檢視加入到父檢視中。
如:inflater.inflate(R.layout.login,MyView);
這種情況不好控制新檢視的長寬。建議使用第一種。
注: LayoutInflater.inflate()將Layout檔案轉換為View,專門供Layout使用的Inflater。雖然Layout也是 View的子類,但在android中如果想將xml中的Layout轉換為View放入.java程式碼中操作,只能通過Inflater,而不能通過 findViewById()。
第二種方法:使用View的靜態方法:
static View inflate(Context context, int resource, ViewGroup root)
引數1:Acitivity或Application的上下文
引數2:指定的xml佈局檔案
引數3:指定父元件。
同樣可以通過:
View view=View.inflate(this,R.layout.*,null);
生成一個新的View,然後呼叫Add方法指定View的屬性並加入的父元件中。
當然也可以使用View.inflate(this,R.layout.*,MyView)直接加入到父元件中。
findViewById有兩種形式 :
R.layout.xx是引用res/layout/xx.xml的佈局檔案(inflate 方法),R.id.xx是引用佈局檔案裡面的元件,元件的id是xx(findViewById方法)。所有的元件id都能用R.id.xx來檢視,但是 元件不在setContentView()裡面的layout中就無法使用,Activity.findViewById()會出現空指標異常
a. activity中的findViewById(int id)
b. View 中的findViewById(int id)
6.不同點是LayoutInflater是用來找layout下xml佈局檔案,並且例項化!而findViewById()是找具體xml下的具體 widget控制元件(如:Button,TextView等)。
Android上還有一個與Inflate()類似功能的方法叫findViewById(),二者有時均可使用,但也有區別,
區別在於:
findViewById()只能找出當前佈局中的元件,即setConentView()的那個layout裡的元件.
如果你的Activity裡用到別的layout,比如對話方塊layout,你還要設定這個layout上的其他元件的內容,你就必須用inflate()方法先將對話方塊的layout找出來,然後再用findViewById()找到它上面的其它元件。例如:
View view1=View.inflate(this,R.layout.dialog_layout,null);
TextViewdialogTV=(TextView)view1.findViewById(R.id.dialog_tv);
dialogTV.setText("abcd");
注:R.id.dialog_tv是在對話方塊layout上的元件,而這時若直接用this.findViewById(R.id.dialog_tv)肯定會報錯。
View viewStub = ((ViewStub) findViewById(R.id.stubView)).inflate();
歡迎掃描二維碼,關注公眾賬號