main布局:
<?
xml version=
"1.0"
encoding=
"utf-8"
?>
<LinearLayout xmlns: android = "http://schemas.android.com/apk/res/android"
android :id= "@+id/layoutContent"
android :layout_width= "match_parent"
android :layout_height= "match_parent"
android :orientation= "vertical" >
</LinearLayout>
<LinearLayout xmlns: android = "http://schemas.android.com/apk/res/android"
android :id= "@+id/layoutContent"
android :layout_width= "match_parent"
android :layout_height= "match_parent"
android :orientation= "vertical" >
</LinearLayout>
待加载布局文件:
<?
xml version=
"1.0"
encoding=
"utf-8"
?>
<RelativeLayout xmlns: android = "http://schemas.android.com/apk/res/android"
android :id= "@+id/layout1"
android :layout_width= "200dp"
android :layout_height= "300dp"
android :background= "@color/Color_D" >
<Button
android :layout_width= "wrap_content"
android :layout_height= "wrap_content"
android :text= "100"
android :layout_centerInParent= "true" />
</RelativeLayout>
<RelativeLayout xmlns: android = "http://schemas.android.com/apk/res/android"
android :id= "@+id/layout1"
android :layout_width= "200dp"
android :layout_height= "300dp"
android :background= "@color/Color_D" >
<Button
android :layout_width= "wrap_content"
android :layout_height= "wrap_content"
android :text= "100"
android :layout_centerInParent= "true" />
</RelativeLayout>
1、inflate(resource, null):
代码:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState) ;
setContentView(R.layout. activity_main) ;
LinearLayout layoutContent = (LinearLayout) findViewById(R.id. layoutContent) ;
View view = LayoutInflater. from( this).inflate(R.layout. layout1 , null) ;
layoutContent.addView(view) ;
}
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState) ;
setContentView(R.layout. activity_main) ;
LinearLayout layoutContent = (LinearLayout) findViewById(R.id. layoutContent) ;
View view = LayoutInflater. from( this).inflate(R.layout. layout1 , null) ;
layoutContent.addView(view) ;
}
结果:
待加载布局文件中layout_width、layout_height参数不起作用
2、inflate(resource, root,true):
将上述java代码改为:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState) ;
setContentView(R.layout. activity_main) ;
LinearLayout layoutContent = (LinearLayout) findViewById(R.id. layoutContent) ;
View view = LayoutInflater. from( this).inflate(R.layout. layout1 , layoutContent , true) ;
layoutContent.addView(view) ;
}
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState) ;
setContentView(R.layout. activity_main) ;
LinearLayout layoutContent = (LinearLayout) findViewById(R.id. layoutContent) ;
View view = LayoutInflater. from( this).inflate(R.layout. layout1 , layoutContent , true) ;
layoutContent.addView(view) ;
}
运行,程序崩溃。
再次将代码改为如下形式:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState) ;
setContentView(R.layout. activity_main) ;
LinearLayout layoutContent = (LinearLayout) findViewById(R.id. layoutContent) ;
View view = LayoutInflater. from( this).inflate(R.layout. layout1 , layoutContent , true) ;
}
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState) ;
setContentView(R.layout. activity_main) ;
LinearLayout layoutContent = (LinearLayout) findViewById(R.id. layoutContent) ;
View view = LayoutInflater. from( this).inflate(R.layout. layout1 , layoutContent , true) ;
}
程序成功运行,且带加载布局文件中的layout_width、layout_height参数有效。
3、inflate(resource, root, false):
将上述java代码改为:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState) ;
setContentView(R.layout. activity_main) ;
LinearLayout layoutContent = (LinearLayout) findViewById(R.id. layoutContent) ;
View view = LayoutInflater. from( this).inflate(R.layout. layout1 , layoutContent , false) ;
}
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState) ;
setContentView(R.layout. activity_main) ;
LinearLayout layoutContent = (LinearLayout) findViewById(R.id. layoutContent) ;
View view = LayoutInflater. from( this).inflate(R.layout. layout1 , layoutContent , false) ;
}
程序可正常运行,但不显示待加载View
再次将上述java代码改为:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState) ;
setContentView(R.layout. activity_main) ;
LinearLayout layoutContent = (LinearLayout) findViewById(R.id. layoutContent) ;
View view = LayoutInflater. from( this).inflate(R.layout. layout1 , layoutContent , false) ;
layoutContent.addView(view) ;
}
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState) ;
setContentView(R.layout. activity_main) ;
LinearLayout layoutContent = (LinearLayout) findViewById(R.id. layoutContent) ;
View view = LayoutInflater. from( this).inflate(R.layout. layout1 , layoutContent , false) ;
layoutContent.addView(view) ;
}
程序正常运行,且待加载布局文件中的layout_width、layout_height有效。
4、inflate(resource, null,false):
将上述java代码改为:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState) ;
setContentView(R.layout. activity_main) ;
LinearLayout layoutContent = (LinearLayout) findViewById(R.id. layoutContent) ;
View view = LayoutInflater. from( this).inflate(R.layout. layout1 , null, false) ;
layoutContent.addView(view) ;
}
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState) ;
setContentView(R.layout. activity_main) ;
LinearLayout layoutContent = (LinearLayout) findViewById(R.id. layoutContent) ;
View view = LayoutInflater. from( this).inflate(R.layout. layout1 , null, false) ;
layoutContent.addView(view) ;
}
程序正常运行,但待加载布局文件中的layout_width、layout_height不起作用
5、inflate(resource, null, true):
将上述java代码改为:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState) ;
setContentView(R.layout. activity_main) ;
LinearLayout layoutContent = (LinearLayout) findViewById(R.id. layoutContent) ;
View view = LayoutInflater. from( this).inflate(R.layout. layout1 , null, true) ;
layoutContent.addView(view) ;
}
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState) ;
setContentView(R.layout. activity_main) ;
LinearLayout layoutContent = (LinearLayout) findViewById(R.id. layoutContent) ;
View view = LayoutInflater. from( this).inflate(R.layout. layout1 , null, true) ;
layoutContent.addView(view) ;
}
程序正常运行,但待加载布局文件中的layout_width、layout_height不起作用
再次将上述java代码改为:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState) ;
setContentView(R.layout. activity_main) ;
LinearLayout layoutContent = (LinearLayout) findViewById(R.id. layoutContent) ;
View view = LayoutInflater. from( this).inflate(R.layout. layout1 , null, true) ;
}
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState) ;
setContentView(R.layout. activity_main) ;
LinearLayout layoutContent = (LinearLayout) findViewById(R.id. layoutContent) ;
View view = LayoutInflater. from( this).inflate(R.layout. layout1 , null, true) ;
}
程序正常运行,不显示待加载view
inflate()方法源码分析:
public View
inflate(XmlPullParser parser
, ViewGroup root
, boolean attachToRoot) {
synchronized ( mConstructorArgs) {
Trace.traceBegin(Trace.TRACE_TAG_VIEW , "inflate") ;
final AttributeSet attrs = Xml. asAttributeSet(parser) ;
Context lastContext = (Context) mConstructorArgs[ 0] ;
mConstructorArgs[ 0] = mContext ;
View result = root ;
try {
// Look for the root node.
int type ;
while ((type = parser.next()) != XmlPullParser. START_TAG &&
type != XmlPullParser. END_DOCUMENT) {
// Empty
}
if (type != XmlPullParser. START_TAG) {
throw new InflateException(parser.getPositionDescription()
+ ": No start tag found!") ;
}
final String name = parser.getName() ;
if ( DEBUG) {
System. out.println( "**************************") ;
System. out.println( "Creating root view: "
+ name) ;
System. out.println( "**************************") ;
}
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 , false, false) ;
} else {
// Temp is the root view that was found in the xml
final View temp = createViewFromTag(root , name , attrs , false) ;
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) ;
}
}
if ( DEBUG) {
System. out.println( "-----> start inflating children") ;
}
// Inflate all children under temp
rInflate(parser , temp , attrs , true, 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.
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.
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 ;
} finally {
// Don't retain static reference on context.
mConstructorArgs[ 0] = lastContext ;
mConstructorArgs[ 1] = null;
}
Trace.traceEnd(Trace.TRACE_TAG_VIEW) ;
return result ;
}
}
synchronized ( mConstructorArgs) {
Trace.traceBegin(Trace.TRACE_TAG_VIEW , "inflate") ;
final AttributeSet attrs = Xml. asAttributeSet(parser) ;
Context lastContext = (Context) mConstructorArgs[ 0] ;
mConstructorArgs[ 0] = mContext ;
View result = root ;
try {
// Look for the root node.
int type ;
while ((type = parser.next()) != XmlPullParser. START_TAG &&
type != XmlPullParser. END_DOCUMENT) {
// Empty
}
if (type != XmlPullParser. START_TAG) {
throw new InflateException(parser.getPositionDescription()
+ ": No start tag found!") ;
}
final String name = parser.getName() ;
if ( DEBUG) {
System. out.println( "**************************") ;
System. out.println( "Creating root view: "
+ name) ;
System. out.println( "**************************") ;
}
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 , false, false) ;
} else {
// Temp is the root view that was found in the xml
final View temp = createViewFromTag(root , name , attrs , false) ;
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) ;
}
}
if ( DEBUG) {
System. out.println( "-----> start inflating children") ;
}
// Inflate all children under temp
rInflate(parser , temp , attrs , true, 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.
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.
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 ;
} finally {
// Don't retain static reference on context.
mConstructorArgs[ 0] = lastContext ;
mConstructorArgs[ 1] = null;
}
Trace.traceEnd(Trace.TRACE_TAG_VIEW) ;
return result ;
}
}
一、 如果root != null:
1、如果attachToRoot == false:
// 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) ;
}
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) ;
}
// Inflate all children under temp
rInflate(parser , temp , attrs , true, true) ;
rInflate(parser , temp , attrs , true, true) ;
如代码所示,此时根据root生成layout param,然后将其应用于生成的view,接着递归inflate View的子View,由下面二中的分析可知,最终返回该view。
2、如果attachToRoot == true:
从代码可以看出,此时同样为View设置layoutParam,然后直接将其添加到root中:
if (root !=
null && attachToRoot) {
root.addView(temp , params) ;
}
root.addView(temp , params) ;
}
由于一开始将result设置为root,可知,最终返回的为root,这也解释了,为什么在root !=null且attachToRoot为true时,调用addView()方法会导致崩溃,也就是前面实验2的情况。
二、如果root == null 或者 attachToRoot为false:
if (root ==
null || !attachToRoot) {
result = temp ;
}
result = temp ;
}
由代码可知,此时既不为View设置layoutParams,也不将其添加到root中,由于最终返回result,因此最终将其直接返回。
总结一下:
1、root != null && attachToRoot == false:
根据root为View设置layoutParams,不将该View添加到root上,最终返回该View。
2、root != null && attachToRoot == true:
根据root为View设置layoutParams,接着将该view添加到root上,最终返回root。
3、root == null
不根据root为View设置layoutParams,不将该view添加到root上,最终返回该view。
由代码可以看出,当root == null时,attachToRoot参数无效。
可以看到,最终的结论跟前面的实验结果是相匹配的。