inflater的 源码 理解:
public View inflate(XmlPullParser parser, ViewGroup root, boolean attachToRoot) {
synchronized (mConstructorArgs) {
//根据xml设置生成对应的参数
final AttributeSet attrs = Xml.asAttributeSet(parser);
mConstructorArgs[0] = mContext;
View result = root;
try {
int type;
while ((type = parser.next()) != XmlPullParser.START_TAG &&
type != XmlPullParser.END_DOCUMENT) {
}
if (type != XmlPullParser.START_TAG) {
throw new InflateException(parser.getPositionDescription()
+ ": No start tag found!");
}
final String name = parser.getName();
if (TAG_MERGE.equals(name)) {
if (root == null || !attachToRoot) {
throw new InflateException("merge can be used only with a valid "
+ "ViewGroup root and attachToRoot=true");
}
rInflate(parser, root, attrs);
} else {
//根据Tag生成View,同时传递给该View的参数
View temp = createViewFromTag(name, attrs);
ViewGroup.LayoutParams params = null;
if (root != null) {
//root不null时才执行
//1,根据attr生成params
//2,attachToRoot为false时意味着不将该view添加到父View,那么设置该View的参数
params = root.generateLayoutParams(attrs);
if (!attachToRoot) {
temp.setLayoutParams(params);
}
}
rInflate(parser, temp, attrs);
// root不null时,并且设置将该View添加到当前的父View
if (root != null && attachToRoot) {
root.addView(temp, params);
}
// root为null时,或者设置将该View不添加添加到当前的父View
if (root == null || !attachToRoot) {
result = temp;
}
}
} catch (XmlPullParserException e) {
InflateException ex = new InflateException(e.getMessage());
ex.initCause(e);
throw ex;
} catch (IOException e) {
InflateException ex = new InflateException(
parser.getPositionDescription()
+ ": " + e.getMessage());
ex.initCause(e);
throw ex;
}
return result;
}
}
1, 指定了 父容器 root,同时 第三个参数 为 true 表示添加 : 则主要看这些代码
params = root.generateLayoutParams(attrs);
if (root != null && attachToRoot) {
root.addView(temp, params);
}
2, 指定了父容器root, 同时第三个参数 为 false 表示不添加进去
params = root.generateLayoutParams(attrs);
if (!attachToRoot) {
temp.setLayoutParams(params);
}
我们看到 即使 不添加到 root, 我们的layoutParams (root.generateLayoutParams(attrs) ) 依然会被衡量. 属性值 如 排列方式 按 root的方式算, 如 root是 lineaLayout, 那么就是 线性排列. 如果是 relativeLayout, 那么就是叠加排
跟普通 的布局没什么区别, layout_width 等 你填写的是什么 就是什么
如果 root==null, 那么 第三个参数 其实没什么用, 默认是false. 因为它的调用方式是 : inflate(v, root, root!=null) . 如果 root=null, 那么第三个参数自然就是 false这个时候 layoutparams =null.
如果 你希望在这种情况下 , addview(该 inflate 的 view). 如果你不指定一个layoutparams, 那么它会 自己生成一个默认的, 即 generateDefaultLayoutParams() 方法. 这个方法各个布局略有不一样
如果你加入的 是 一个 linearlayout : 这个方法是这样的.(纵向的情况下, 宽度为 match_parent)
@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;
}
如果你 加入的 是一个 RelativeLayout , 那么这个方法 是:
@Override
protected ViewGroup.LayoutParams generateDefaultLayoutParams() {
return new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
}
and a FrameLayout is : (that's very surprised)
return new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
return new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
return new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);