對LayoutInflater的一些理解記錄
通過在查看一些關(guān)于LayoutInflater的資料稀颁,整理成為自己的理解。
相關(guān)的鏈接:
//Android獲取LayoutInflater對象的方法總結(jié)
http://blog.csdn.net/bigconvience/article/details/26582497
//詳解LayoutInflater.inflate()
https://zhuanlan.zhihu.com/p/23334059
//[譯轉(zhuǎn)]深入理解LayoutInflater.inflate()
https://zhuanlan.zhihu.com/p/23334059
我將這些資料分為兩步來理解:
第一步:Android獲取LayoutInflater對象的方法(分為三種情況):
a)、若能獲取LayoutInflater對象時:
1、LayoutInflater inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
? ? ? View?child?=?inflater.inflate(R.layout.child,null);
2、LayoutInflater inflater = LayoutInflater.from(context);
? ? ? View?child?=?inflater.inflate(R.layout.child,null);
b)在Activity中時:
1、View child = getLayoutInflater().inflate(R.layout.child, item,false);
2谋减、View view;
? ? ?LayoutInflater?inflater?=?(LayoutInflater)???getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
? ? ?view?=?inflater.inflate(R.layout.mylayout,null);
c)在使用View的靜態(tài)方法時:
1、View view=View.inflate(context, R.layout.child,null)
第二步:inflate()中的attachToRoot扫沼,何時為true出爹,何時為false?
a)attachToRoot為true時:(layout文件會被填充并且附加在ViewGroup內(nèi))
例如:
1庄吼、inflate(R.layout.xxx,parent,true);
2、inflate(R.layout.xxx,parent);
3严就、inflater.inflate(R.layout.xxx,this);
b)attachToRoot為false時:(layout文件會被填充,但是不會附加在ViewGroup內(nèi)总寻,需要自己手動去addview加進(jìn)去)
例如:
1、inflate(R.layout.xxx,parent,false);
使用LayoutInflater時避開崩潰梢为、異常表現(xiàn)與誤解
1渐行、如果可以傳入ViewGroup作為根元素,那就傳入它铸董。
2祟印、避免將null作為根ViewGroup傳入。
3粟害、當(dāng)我們不負(fù)責(zé)將layout文件的View添加進(jìn)ViewGroup時設(shè)置attachToRoot參數(shù)為false蕴忆。
4、不要在View已經(jīng)被添加進(jìn)ViewGroup時傳入true悲幅。
5套鹅、自定義View時很適合將attachToRoot設(shè)置為true。
下面的這段內(nèi)容是引用別人的:
//詳解LayoutInflater.inflate()
https://zhuanlan.zhihu.com/p/23334059
就拿我們的Adapter來說吧汰具,在創(chuàng)建item布局時卓鹿,有下列幾種情況:
inflate(R.layout.xxx,null);
inflate(R.layout.xxx,parent,false);
inflate(R.layout.xxx,parent,true);
那么就講一下這三種情況把。
首先留荔,inflate(R.layout.xxx,null) 吟孙。這是最簡單的寫法,這樣生成的布局就是根據(jù)http://R.layout.xxx返回的View存谎。要知道拔疚,這個布局文件中的寬高屬性都是相當(dāng)于父布局而言的肥隆。由于沒有指定parent既荚,所以他的寬高屬性就失效了,因此不管你怎么改寬高屬性栋艳,都無法按你想象的那樣顯示恰聘。
然后,inflate(R.layout.xxx,parent,false)吸占。相較于前者晴叨,這里加了父布局,不管后面是true還是false矾屯,由于有了parent兼蕊,布局文件的寬高屬性是有依靠了,這時候顯示的寬高樣式就是布局文件中的那樣了件蚕。
最后孙技,inflate(R.layout.xxx,parent,true)产禾。這樣……等等,報(bào)錯了牵啦?亚情??哦哈雏,不要驚奇楞件,分析一下原因:首先,有了parent裳瘪,所以可以正確處理布局文件的寬高屬性土浸。然后,既然attachToRoot為true盹愚,那么根據(jù)上面的源碼就會知道栅迄,這里會調(diào)用root的addView方法。而如果root是listView等皆怕,由于他們是繼承自AdapterView的毅舆,看看AdapterView的addView方法:
@OverridepublicvoidaddView(Viewchild){
thrownewUnsupportedOperationException("addView(View) is not supported in AdapterView");}
不資磁啊,那好吧愈腾,如果換成RecyclerView呢憋活?還是報(bào)錯了,看看源碼:
if(child.getParent()!=null){
thrownewIllegalStateException("The specified child already has a parent. "+"You must call removeView() on the child's parent first.");}
現(xiàn)在知道了吧虱黄,adpater里面不要用true悦即。那么什么時候用true呢?答案是fragment橱乱。在為fragment創(chuàng)建布局時辜梳,如果為true,那么這個布局文件就會被添加到父activity中盛放fragment的布局中泳叠。