LayoutInflater的使用有下面4种方法:
- LayoutInflater.from(this).inflate(R.layout.xxx, null)
- LayoutInflater.from(this).inflate(R.layout.xxx, parent)
- LayoutInflater.from(this).inflate(R.layout.xxx, parent,true)
- LayoutInflater.from(this).inflate(R.layout.xxx, parent,false)
点进inflate()方法源码发现都调用了下面这个三个参数的方法
public View inflate(@LayoutRes int resource, @Nullable ViewGroup root, boolean attachToRoot) {
final Resources res = getContext().getResources();
if (DEBUG) {
Log.d(TAG, "INFLATING from resource: \"" + res.getResourceName(resource) + "\" ("
+ Integer.toHexString(resource) + ")");
}
View view = tryInflatePrecompiled(resource, res, root, attachToRoot);
if (view != null) {
return view;
}
XmlResourceParser parser = res.getLayout(resource);
try {
return inflate(parser, root, attachToRoot);
} finally {
parser.close();
}
}
两个参数的方法最终也调用了上面三个参数的方法
public View inflate(XmlPullParser parser, @Nullable ViewGroup root) {
return inflate(parser, root, root != null);
}
会发现:使用方法2=使用方法3
最终调用带解析器的inflate方法
public View inflate(XmlPullParser parser, @Nullable ViewGroup root, boolean attachToRoot) {
synchronized (mConstructorArgs) {
Trace.traceBegin(Trace.TRACE_TAG_VIEW, "inflate");
final Context inflaterContext = mContext;
final AttributeSet attrs = Xml.asAttributeSet(parser);
Context lastContext = (Context) mConstructorArgs[0];
mConstructorArgs[0] = inflaterContext;
View result = root;
try {
//省略了一些判断等代码 重点是下面这段代码
......
//1.获取xml解析器的名字
final String name = parser.getName();
// Temp is the root view that was found in the xml
//2.用动态反射的方法把name创建成View,这个temp就是xml最外层的rootview,
// 但是这个创建出来的view是没有设置属性的(宽,高,边距)
final View temp = createViewFromTag(root, name, inflaterContext, attrs);
ViewGroup.LayoutParams params = null
if (root != null) {
if (DEBUG) {
System.out.println("Creating params from root: " +
root);
}
// Create layout params that match root, if supplied
params = root.generateLayoutParams(attrs);
//3.如果parent传入的不是null 并且attachToRoot =false 就给temp设置属性,最后会返回temp
if (!attachToRoot) {
// Set the layout params for temp if we are not
// attaching. (If we are, we use addView, below)
temp.setLayoutParams(params);
}
}
if (DEBUG) {
System.out.println("-----> start inflating children");
}
// Inflate all children under temp against its context.
rInflateChildren(parser, temp, attrs, true);
if (DEBUG) {
System.out.println("-----> done inflating children");
}
// We are supposed to attach all the views we found (int temp)
// to root. Do that now.
//4.如果parent传的不是null 并且attachToRoot =true,就把xml和属性添加到 parent中
if (root != null && attachToRoot) {
root.addView(temp, params);
}
// Decide whether to return the root that was passed in or the
// top view found in xml.
//5. 如果parent传的是null或者attachToRoot==false,则把xml反射创建出来,不设置属性返回
if (root == null || !attachToRoot) {
result = temp;
}
......
return result;
}
}
总结:
- parent 传空,即:第二个参数是null ,就把xml动态创建成View ,不设置属性(宽高,边距等),然后返回View
- LayoutInflater.from(this).inflate(R.layout.xxx, parent)等同于LayoutInflater.from(this).inflate(R.layout.xxx, parent,true)
把xml创建成view,设置属性并添加到parent中,然后返回parent,注意这里是把xml 添加到parent里,return的是parent! - LayoutInflater.from(this).inflate(R.layout.xxx, parent,false)
把xml创建成view并设置了属性,然后返回view