1.inflate 的 参数详解
public View inflate(@LayoutRes int resource, @Nullable ViewGroup root, boolean attachToRoot)
resource : 资源文件
root :父节点
attachToRoot : 表示是否将resource指定的布局添加到root中
2.root 为 null 或 非null 时区别
root 为 null 时,resource的顶层结点宽高和间距
都不生效
root 不为 null 时,resource 便根据 root 来决定
**让我们跟进源码来解析 **
2.1 root 为null时
View view = LayoutInflater.from(MainActivity.this).inflate(R.layout.activity_test,null);
ll.addView(view)//Linearlayout
此时一直跟进到
//LayoutInflater.java
public View inflate(XmlPullParser parser, @Nullable ViewGroup root, boolean attachToRoot) {
//上面代码忽略
// Temp is the root view that was found in the xml
final View temp = createViewFromTag(root, name, inflaterContext, attrs);//此时 temp 没有 mLayoutParams
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);
if (!attachToRoot) {
// Set the layout params for temp if we are not
// attaching. (If we are, we use addView, below)
temp.setLayoutParams(params);
}
}
//下面代码忽略
}
由上可知,当 root
为空时,temp 的 mLayoutParams 未赋值,故 temp 没有布局参数
注意:temp没有布局参数,但是temp的child都有 mLayoutParams
接下来分析 ll.addView(view)
//ViewGroup.java
public void addView(View child, int index) {
if (child == null) {
throw new IllegalArgumentException("Cannot add a null child view to a ViewGroup");
}
LayoutParams params = child.getLayoutParams();
if (params == null) {
params = generateDefaultLayoutParams();
if (params == null) {
throw new IllegalArgumentException("generateDefaultLayoutParams() cannot return null");
}
}
addView(child, index, params);
}
//LinearLayout.java
@Override
protected LayoutParams generateDefaultLayoutParams() {
if (mOrientation == HORIZONTAL) {
return new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
} else if (mOrientation == VERTICAL) {
return new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
}
return null;
}
可以看到当 view 的 mLayoutParams
为空时,会给 view 设置一个 LayoutParams
2.2 root 不为 null 时
由上面代码可知,当root不为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);
if (!attachToRoot) {
// Set the layout params for temp if we are not
// attaching. (If we are, we use addView, below)
temp.setLayoutParams(params);
}
}
当attachToRoot为false时,此时会执行 temp.setLayoutParams(params);
,那么view就有宽高间距等属性,那么 ll.addView(view)
就直接用view的布局了
3. attachToRoot 为false或true的区别
attachToRoot 为 false 时,会给根据layout生成的view赋值
if (!attachToRoot) {
// Set the layout params for temp if we are not
// attaching. (If we are, we use addView, below)
temp.setLayoutParams(params);
}
attachToRoot 为 true 时,自动将布局加入到 root 中
if (root != null && attachToRoot) {
root.addView(temp, params);
}
4.总结
LayoutInflater.get(context).inflate(1,2,3) 核心方法就是
public View inflate(XmlPullParser parser, @Nullable ViewGroup root, boolean attachToRoot) {}
当 root 为 null 时,生成的 View mLayoutParmas=null
当 root 不为 null 时,生成的 View 有 mLayoutParams 字段
当 attachToRoot 为 true 时,会执行 root.addView(view,params)
方法 ,所以不用手动加