對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加進去)
例如:
1、inflate(R.layout.xxx,parent,false);
使用LayoutInflater時避開崩潰、異常表現(xiàn)與誤解
1、如果可以傳入ViewGroup作為根元素,那就傳入它。
2、避免將null作為根ViewGroup傳入。
3、當(dāng)我們不負(fù)責(zé)將layout文件的View添加進ViewGroup時設(shè)置attachToRoot參數(shù)為false。
4、不要在View已經(jīng)被添加進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)。這樣……等等,報錯了???哦,不要驚奇,分析一下原因:首先,有了parent,所以可以正確處理布局文件的寬高屬性。然后,既然attachToRoot為true,那么根據(jù)上面的源碼就會知道,這里會調(diào)用root的addView方法。而如果root是listView等,由于他們是繼承自AdapterView的,看看AdapterView的addView方法:
@OverridepublicvoidaddView(Viewchild){
thrownewUnsupportedOperationException("addView(View) is not supported in AdapterView");}
不資磁啊,那好吧,如果換成RecyclerView呢?還是報錯了,看看源碼:
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的布局中。