LayoutInflater中inflatepublic View inflate(@LayoutRes int resource, @Nullable ViewGroup root, boolean attachToRoot)
1.1 root不为null,attachToRoot为true
当root不为null,attachToRoot为true时,表示将resource指定的布局添加到root中,
添加的过程中resource所指定的的布局的根节点的各个属性都是有效的
且会自动添加到 root中
View view = inflater.inflate(R.layout.linearlayout, ll, true);
ll.addView(view);
//报错 java.lang.IllegalStateException: The specified child already has a parent.
You must call removeView() on the child's parent first.
原因就是因为当第三个参数为true时,会自动将第一个参数所指定的View添加到第二个参数所指定的View中。
1.2 root不为null,attachToRoot为false
如果root不为null,而attachToRoot为false的话,表示不将第一个参数所指定的View添加到root中
如果我想让linearlayout的根节点有效,又不想让其处于某一个容器中,那我就可以设置root不为null,而attachToRoot为false。
这样,指定root的目的也就很明确了,即root会协助linearlayout的根节点生成布局参数,只有这一个作用
View view = inflater.inflate(R.layout.linearlayout, ll, false);
ll.addView(view);
1.3 root为null
当root为null时,不论attachToRoot为true还是为false,显示效果都是一样的。当root为null表示我不需要将
第一个参数所指定的布局添加到任何容器中,同时也表示没有任何容器来来协助第一个参数所指定布局的根节
点生成布局参数。
DecorView
视图结构
DecorView为整个Window界面的最顶层View。 二、DecorView只有一个子元素为LinearLayout。代表整个Window界面,
包含通知栏,标题栏,内容显示栏三块区域。 三、LinearLayout里有两个FrameLayout子元素。
Activity----|
|-DecorView-|----LinearLayout里有两个FrameLayout子元素
|
|-ActionBar |
|------------
|ContentParent
|
ViewStub
ViewStub 直接继承自View,是一种不可见,0大小的可以在运行的时候再加载的View
特点:
ViewStub只能被Inflate一次,inflate之后ViewStub对象就会被置为空
ViewStub只能用来Inflate一个布局文件,而不是某个具体的View,当然也可以把View写在某个布局文件中
使用步骤
1.android:id——ViewStub 自身的Id,无论是否被inflate,都可以通过findViewById拿到对应的ViewStub控件本身
2.android:inflatedId——ViewStub设置的被映射的布局文件中的跟节点的Id,inflate之后可以通过findViewById
获取到对应的被映射的布局对象。
3.android:layout——将要映射的布局文件名,注意和include 标签里的区分(include标签是layout:)
4.ViewStub.OnInflateListener——当ViewStub成功映射预先设置的布局会触发回调
(Listener used to receive a notification after a ViewStub has successfully inflated its layout resource)
判断ViewStub是否被inflate 过的方式。
1.如果ViewStub没有 inflate 在其布局文件中能通过findviewByID 找到对应 ViewStub 不能null ,反之 找不到
2.ViewStub infalte 之后 viewStub.getParent() 为空