我们通常使用addView
这个方法时,会先通过LayoutInflater
的inflate
生成一个View
视图,然后添加到当前ViewGroup
中,如果使用不恰当,就会出现这样的问题:
setContentView(R.layout.layout_inflate_test);
LinearLayout viewGroup = (LinearLayout) findViewById(R.id.root);
//1.inflate_test根布局layout参数被忽略
// View v = LayoutInflater.from(this).inflate(R.layout.inflate_test, null);
// viewGroup.addView(v);
//2.不会忽略
// View v = LayoutInflater.from(this).inflate(R.layout.inflate_test, viewGroup, false);
// viewGroup.addView(v);
//3.不会忽略
// LayoutInflater.from(this).inflate(R.layout.inflate_test, viewGroup);
//4.不会忽略
// LayoutInflater.from(this).inflate(R.layout.inflate_test, viewGroup, true);
上面的代码中,第一种用法根布局layout参数会被忽略,后面都不会。我们从LayoutInflater源码中可以看出来原因,在public View inflate(XmlPullParser parser, ViewGroup root, boolean attachToRoot)
方法中:
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
不为空,且attachToRoot
为false
,会把布局参数params
加上。
if (root != null && attachToRoot) {
root.addView(temp, params);
}
如果root
不为空,且attachToRoot
为true
,会通过addView(temp, params)
方法加上布局参数。
因此,我们不能因为暂时不需要绑定到root
上面就忽视掉root的作用,没有的话设置的布局参数就不起作用了哦!
比如我们在使用ListView的时候就经常碰到,ListView
添加HeaderView之后尺寸布局被忽略的情况:
通常添加头部的方法是
LayoutInflater lif = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View headerView = lif.inflate(R.layout.header, null);
mListView.addHeaderView(headerView);
原因就是lif.inflate(R.layout.header, null)
丢失了XML布局中根View
的LayoutParam
,其实使用下面的方法就可以了:
lif.inflate(R.layout.header, mListView, false);