转自:https://blog.csdn.net/u012702547/article/details/52628453?utm_source=copy

inflate方法从大范围来看,分两种,三个参数的构造方法和两个参数的构造方法。在这两类中又有细分,OK,那我们就把各种情况都来演示一遍。

1.三个参数的inflate方法
方法头如下:

public View inflate(@LayoutRes int resource, @Nullable ViewGroup root, boolean attachToRoot)

好,这里主要分为三种情况,分别来看

1.1 root不为null,attachToRoot为true

当root不为null,attachToRoot为true时,表示将resource指定的布局添加到root中,添加的过程中resource所指定的的布局的根节点的各个属性都是有效的。比如下面一个案例,我的Activity的布局如下:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:id="@+id/ll"
tools:context="org.sang.layoutinflater.MainActivity">
</LinearLayout>

我还有一个布局linearlayout.xml如下:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/ll"
android:layout_width="200dp"
android:layout_height="200dp"
android:background="@color/colorPrimary"
android:gravity="center"
android:orientation="vertical"> <Button
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>

我现在想把这个linearlayout.xml布局文件添加到我的activity的布局中,那么我可以这么做:

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
LinearLayout ll = (LinearLayout) findViewById(R.id.ll);
LayoutInflater inflater = LayoutInflater.from(this);
inflater.inflate(R.layout.linearlayout, ll,true); //将第一个参数所指定的布局添加到第二个参数的View中
}

小伙伴们注意到,这里我都没写将inflate出来的View添加到ll中的代码,但是linearlayout布局文件就已经添加进来了,这就是因为我第三个参数设置为了true,表示将第一个参数所指定的布局添加到第二个参数的View中。最终显示效果如下:

如果我作死多写这么一行代码,如下:

protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
LinearLayout ll = (LinearLayout) findViewById(R.id.ll);
LayoutInflater inflater = LayoutInflater.from(this);
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中。

这里涉及到另外一个问题:我们在开发的过程中给控件所指定的layout_width和layout_height到底是什么意思?

该属性的表示一个控件在容器中的大小,就是说这个控件必须在容器中,这个属性才有意义,否则无意义。这就意味着如果我直接将linearlayout加载进来而不给它指定一个父布局,则inflate布局的根节点的layout_width和layout_height属性将会失效(因为这个时候linearlayout将不处于任何容器中,那么它的根节点的宽高自然会失效)。

如果我想让linearlayout的根节点有效,又不想让其处于某一个容器中,那我就可以设置root不为null,而attachToRoot为false。

这样,指定root的目的也就很明确了,即root会协助linearlayout的根节点生成布局参数,只有这一个作用。

OK,还是上面的布局文件,如果我想将之添加到activity的布局中又该如何呢?

protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
LinearLayout ll = (LinearLayout) findViewById(R.id.ll);
LayoutInflater inflater = LayoutInflater.from(this);
View view = inflater.inflate(R.layout.linearlayout, ll, false);
ll.addView(view);
}

大家注意,这个时候我需要手动的将inflate加载进来的view添加到ll容器中,因为inflate的最后一个参数false表示不将linealayout添加到ll中。显示效果和上文一样,不再贴图。

1.3 root为null

当root为null时,不论attachToRoot为true还是为false,显示效果都是一样的。当root为null表示我不需要将第一个参数所指定的布局添加到任何容器中,同时也表示没有任何容器来来协助第一个参数所指定布局的根节点生成布局参数。我还是使用上文提到的linearlayout,我们来看下面一段代码:

protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
LinearLayout ll = (LinearLayout) findViewById(R.id.ll);
LayoutInflater inflater = LayoutInflater.from(this);
View view = inflater.inflate(R.layout.linearlayout, null, false);
ll.addView(view);
}

当第二个参数为null,第三个参数为false时(即使为true显示效果也是一样的,这里以false为例),由于在inflate方法中没有将linearlayout添加到某一个容器中,所以我需要手动添加,另外由于linearlayout并没有处于某一个容器中,所以它的根节点的宽高属性会失效,显示效果如下:

小伙伴们注意,这个时候不管我给linearlayout的根节点的宽高设置什么,都是没有效果的,它都是包裹button,如果我修改button,则button会立即有变化,因为button是处于某一个容器中的。

2.两个参数的inflate方法

两个参数的inflate方法就很简单了,我们来稍微看一点点源码:

public View inflate(XmlPullParser parser, @Nullable ViewGroup root) {
return inflate(parser, root, root != null);
}

这是两个参数的inflate方法,大家注意两个参数实际上最终也是调用了三个参数。
两个参数的inflate方法分为如下两种情况:

1.root为null,等同于1.3所述情况。

2.root不为null,等同于1.1所述情况。

3.为什么Activity布局的根节点的宽高属性会生效?

inflate方法我们已经说完了,小伙伴们可能有另外一个疑问,那为什么Activity布局的根节点的宽高属性会生效?其实原因很简单,大部分情况下我们一个Activity页面由两部分组成(Android的版本号和应用主题会影响到Activity页面组成,这里以常见页面为例),我们的页面中有一个顶级View叫做DecorView,DecorView中包含一个竖直方向的LinearLayout,LinearLayout由两部分组成,第一部分是标题栏,第二部分是内容栏,内容栏是一个FrameLayout,我们在Activity中调用setContentView就是将View添加到这个FrameLayout中,所以给大家一种错觉仿佛Activity的根布局很特殊,其实不然。

OK,以上就是对LayoutInflater中inflate方法的一个简单介绍,希望能够帮助到还没弄懂这个的小伙伴。

android inflate压力泵,将视图发生整合的过程的更多相关文章

  1. mybatis学习笔记(五) -- maven+spring+mybatis从零开始搭建整合详细过程(附demo和搭建过程遇到的问题解决方法)

    文章介绍结构一览 一.使用maven创建web项目 1.新建maven项目 2.修改jre版本 3.修改Project Facts,生成WebContent文件夾 4.将WebContent下的两个文 ...

  2. UIViewController的生命周期(根视图view从无到有的过程)

    UIViewController的生命周期实质上是指根视图view从无到有的过程 1.首先新建一个工程:不从mainstoryBoard加载 (删除入口) 在AppDelegate.m --> ...

  3. .Net程序员学用Oracle系列(7):视图、函数、过程、包

    <.Net程序员学用Oracle系列:导航目录> 本文大纲 1.视图 1.1.创建视图 2.函数 2.1.创建函数 2.2.调用函数 3.过程 3.1.创建过程 3.2.调用过程 4.包 ...

  4. Android图表库MPAndroidChart(四)——条形图的绘制过程过程,隐隐约约我看到了套路

    Android图表库MPAndroidChart(四)--条形图的绘制过程过程,隐隐约约我看到了套路 在学习本课程之前我建议先把我之前的博客看完,这样对整体的流程有一个大致的了解 Android图表库 ...

  5. mybatis学习笔记(六) -- maven+spring+mybatis从零开始搭建整合详细过程(下)

    继续 mybatis学习笔记(五) -- maven+spring+mybatis从零开始搭建整合详细过程(上) 五.使用监听器启动Spring容器 1.修改pom.xml文件,添加Spring-we ...

  6. ZT Android 4.2 BT系统之蓝牙关闭过程全跟踪

    Android 4.2 BT系统之蓝牙关闭过程全跟踪 分类: android 2013-08-03 00:34 2252人阅读 评论(10) 收藏 举报 代码位置:       frameworks/ ...

  7. 【Android实战】记录自学自己定义GifView过程,能同一时候支持gif和其它图片!【有用篇】

    之前写了一篇博客.<[Android实战]记录自学自己定义GifView过程,具体解释属性那些事! [学习篇]> 关于自己定义GifView的,具体解说了学习过程及遇到的一些类的解释,然后 ...

  8. 一文读懂 Android TouchEvent 事件分发、拦截、处理过程

    什么是事件?事件是用户触摸手机屏幕,引起的一系列TouchEvent,包括ACTION_DOWN.ACTION_MOVE.ACTION_UP.ACTION_CANCEL等,这些action组合后变成点 ...

  9. Android 自学之列表视图ListView和ListActivity

    ListView是手机系统中使用非常广泛的一种组件,它以垂直列表的形式显示所有列表项. 创建ListView有两种方式: 直接使用ListView创建. 让Activity继承ListActivity ...

随机推荐

  1. 467. Unique Substrings in Wraparound String

    Consider the string s to be the infinite wraparound string of "abcdefghijklmnopqrstuvwxyz" ...

  2. CTF之信息泄漏

    web源码泄漏 .hg源码泄漏: 漏洞成因:hg  init的时候会生成.hg,http://www.xx.com/.hg/, 工具:dvcs-ripper,(rip-hg.pl -v -u http ...

  3. CodeChef March Challenge 2019题解

    传送门 \(CHNUM\) 显然正数一组,负数一组 for(int T=read();T;--T){ n=read(),c=d=0; fp(i,1,n)x=read(),x>0?++c:++d; ...

  4. 利用jaxb实现xml和bean的相互转换

    1.使用jar包生成xsd文件 java -jar trang.jar a.xml a.xsd xml格式 生成的xsd文件 2.使用xjc命令生成bean文件 xjc a.xsd 生成的相关bean ...

  5. rpm -ivh 这个ivh是干什么的

    安装的时候显示安装进度 --从百度知道复制过来的 RMP 是 LINUX 下的一种软件的可执行程序,你只要安装它就可以了.这种软件安装包通常是一个RPM包(Redhat Linux Packet Ma ...

  6. HTML实例(四)

    实例一:有序列表,无序列表,<dl>,<dt>,<dd>,div块级标签等,实现上面的效果. <!DOCTYPE html> <html lang ...

  7. JavaScript创建对象的4种方法

    我们有很多种方式去构造一个对象.可以构造一个对象字面量,也可以和new前缀连用去调用一个构造器函数,或者可以使用Object.create方法去构造一个已经存在的对象的新实例,还可以调用任意一个会返回 ...

  8. P1091 合唱队列

    合唱队列 原题:传送门 核心代码: /* 方法求出每一个点的最长升子序列和最长降子序列,再加到该点上 通过循环比较哪个点最大,再用总长减去该点长度即是答案 */ #include<iostrea ...

  9. OS X获取process.env.NODE_ENV出错

    原来项目是其它小组在维护,现在我们需要维护部分功能,把项目带到OS X上运行发现 webpack.config.js获取process.env.NODE_ENV变量出错 解决: 根据电脑操作系统平台类 ...

  10. Openerp 修改 tree view 的列宽

    在 tree 的后边添加自定义css 列:“my_class" 然后在对应的css文件中,添加样式: 保存,重新刷新页面即可.