http://blog.csdn.net/guolin_blog/article/details/12921889
总结:
LayoutInflater内部的inflate()方法其实就是xml的pull解析去创建View(setContentView()内部也是通过LayoutInflater()加载)
查看源码可知inflate()调用了createViewFromTag()方法,把节点名和参数传了进去,createViewFromTag()内部又会去调用createView(),最后通过反射的方式创建View实例并返回,这里只是创建了根布局实例;接下来调用rInflate()方法循环遍历根布局下的子元素也是调用createViewFromTag()递归创建子View
inflate(int resource, ViewGroup root, boolean attachToRoot)中attachToRoot的作用:
如果root为null,attachToRoot失去作用,设置任何值没有任何意义
如果root不为null,attachToRoot设为true,则会给加载的布局文件指定一个父布局root
如果root不为null,attachToRoot设为false,则会将布局文件最外层的所有layout属性进行设置(如layout_width和layout_height等,根据上面分析我们知道LayoutInflater加载的根布局layout属性是无效的),当该View被添加到父View中时,这些layout属性会自动生效
如果root不为null,attachToRoot不设置,默认为true
如果一个layout.xml没有最外层布局(如LinearLayout或RelativeLayout),只有控件本身,则在使用LayoutInflater加载该layout.xml时,该布局的控件无论怎样设置layout_width和layout_height都是无效的,如下:
<Button xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="300dp" android:layout_height="80dp" android:text="button"/>解决方案:在该layout.xml中加上一层布局即可解决(但最外层根布局也受影响设置layout_width和layout_height无效):
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <Button android:layout_width="300dp" android:layout_height="80dp" android:text="button"/> </RelativeLayout>为什么layout_width和layout_height会无效?
原因是layout_width和layout_height是设置View在布局中的大小,而不是设置View自身大小,所以就必须要有外层布局才有效
如果setContentView()是LayoutInflater加载,为什么会有效?
原因是DecorView是一个LinearLayout,包含这TitleBar和ContentView,而ContentView已经在外层存在一个FrameLayout,所有setContentView()时我们的布局就有效