对LayoutInflater的一些理解记录
通过在查看一些关于LayoutInflater的资料,整理成为自己的理解。
相关的链接:
//Android获取LayoutInflater对象的方法总结
http://blog.csdn.net/bigconvience/article/details/26582497
//详解LayoutInflater.inflate()
https://zhuanlan.zhihu.com/p/23334059
//[译转]深入理解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的静态方法时:
1、View view=View.inflate(context, R.layout.child,null)
第二步:inflate()中的attachToRoot,何时为true,何时为false?
a)attachToRoot为true时:(layout文件会被填充并且附加在ViewGroup内)
例如:
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内,需要自己手动去addview加进去)
例如:
1、inflate(R.layout.xxx,parent,false);
使用LayoutInflater时避开崩溃、异常表现与误解
1、如果可以传入ViewGroup作为根元素,那就传入它。
2、避免将null作为根ViewGroup传入。
3、当我们不负责将layout文件的View添加进ViewGroup时设置attachToRoot参数为false。
4、不要在View已经被添加进ViewGroup时传入true。
5、自定义View时很适合将attachToRoot设置为true。
下面的这段内容是引用别人的:
//详解LayoutInflater.inflate()
https://zhuanlan.zhihu.com/p/23334059
就拿我们的Adapter来说吧,在创建item布局时,有下列几种情况:
inflate(R.layout.xxx,null);
inflate(R.layout.xxx,parent,false);
inflate(R.layout.xxx,parent,true);
那么就讲一下这三种情况把。
首先,inflate(R.layout.xxx,null) 。这是最简单的写法,这样生成的布局就是根据http://R.layout.xxx返回的View。要知道,这个布局文件中的宽高属性都是相当于父布局而言的。由于没有指定parent,所以他的宽高属性就失效了,因此不管你怎么改宽高属性,都无法按你想象的那样显示。
然后,inflate(R.layout.xxx,parent,false)。相较于前者,这里加了父布局,不管后面是true还是false,由于有了parent,布局文件的宽高属性是有依靠了,这时候显示的宽高样式就是布局文件中的那样了。
最后,inflate(R.layout.xxx,parent,true)。这样……等等,报错了???哦,不要惊奇,分析一下原因:首先,有了parent,所以可以正确处理布局文件的宽高属性。然后,既然attachToRoot为true,那么根据上面的源码就会知道,这里会调用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.");}
现在知道了吧,adpater里面不要用true。那么什么时候用true呢?答案是fragment。在为fragment创建布局时,如果为true,那么这个布局文件就会被添加到父activity中盛放fragment的布局中。