【转】三个案例带你看懂LayoutInflater中inflate方法两个参数和三个参数的区别
关于inflate参数问题,我想很多人多多少少都了解一点,网上也有很多关于这方面介绍的文章,但是枯燥的理论或者翻译让很多小伙伴看完之后还是一脸懵逼,so,我今天想通过三个案例来让小伙伴彻底的搞清楚这个东东。本篇博客我们不讲源码,只看使用。源码的解读会在下一篇博文中带来。
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);
- }
小伙伴们注意到,这里我都没写将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中,那么这个时候有的小伙伴可能就有疑问了,既然不添加到root中,那我还写这么多干嘛?我第二个参数直接给null不就可以了?其实不然,这里涉及到另外一个问题:我们在开发的过程中给控件所指定的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方法
- public View inflate(XmlPullParser parser, @Nullable ViewGroup root) {
- return inflate(parser, root, root != null);
- }
这是两个参数的inflate方法,大家注意两个参数实际上最终也是调用了三个参数。
3.为什么Activity布局的根节点的宽高属性会生效?
inflate方法我们已经说完了,小伙伴们可能有另外一个疑问,那为什么Activity布局的根节点的宽高属性会生效?其实原因很简单,大部分情况下我们一个Activity页面由两部分组成(Android的版本号和应用主题会影响到Activity页面组成,这里以常见页面为例),我们的页面中有一个顶级View叫做DecorView,DecorView中包含一个竖直方向的LinearLayout,LinearLayout由两部分组成,第一部分是标题栏,第二部分是内容栏,内容栏是一个FrameLayout,我们在Activity中调用setContentView就是将View添加到这个FrameLayout中,所以给大家一种错觉仿佛Activity的根布局很特殊,其实不然。
【转】三个案例带你看懂LayoutInflater中inflate方法两个参数和三个参数的区别的更多相关文章
- 三个案例带你看懂LayoutInflater中inflate方法两个参数和三个参数的区别
关于inflate参数问题,我想很多人多多少少都了解一点,网上也有很多关于这方面介绍的文章,但是枯燥的理论或者翻译让很多小伙伴看完之后还是一脸懵逼,so,我今天想通过三个案例来让小伙伴彻底的搞清楚这个 ...
- 带你看懂LayoutInflater中inflate方法
关于inflate问题,我想很多人多多少少都了解一点,网上也有很多关于这方面介绍的文章,但是枯燥的理论或者翻译让很多小伙伴看完之后还是一脸懵逼,so,我今天想通过三个案例来让小伙伴彻底的搞清楚这个东东 ...
- 一文带你看懂Java中的Lock锁底层AQS到底是如何实现的
前言 相信大家对Java中的Lock锁应该不会陌生,比如ReentrantLock,锁主要是用来解决解决多线程运行访问共享资源时的线程安全问题.那你是不是很好奇,这些Lock锁api是如何实现的呢?本 ...
- 从源码带你看懂functools的partial方法
1.what? partial是什么, partial也叫偏函数.源码的描述是: 部分应用给定参数和关键字的新函数. New function with partial application of ...
- 【 全干货 】5 分钟带你看懂 Docker !
欢迎大家前往腾讯云社区,获取更多腾讯海量技术实践干货哦~ 作者丨唐文广:腾讯工程师,负责无线研发部地图测试. 导语:Docker,近两年才流行起来的超轻量级虚拟机,它可以让你轻松完成持续集成.自动交付 ...
- 一篇带你看懂Flutter叠加组件Stack
注意:无特殊说明,Flutter版本及Dart版本如下: Flutter版本: 1.12.13+hotfix.5 Dart版本: 2.7.0 Stack Stack组件可以将子组件叠加显示,根据子组件 ...
- 转://看懂Oracle中的执行计划
一.什么是Oracle执行计划? 执行计划是一条查询语句在Oracle中的执行过程或访问路径的描述 二.怎样查看Oracle执行计划? 2.1 explain plan for命令查看执行计划 在sq ...
- 一文看懂js中元素偏移量(offsetLeft,offsetTop,offsetWidth,offsetHeight)
偏移量(offset dimension) 偏移量:包括元素在屏幕上占用的所有可见空间,元素的可见大小有其高度,宽度决定,包括所有内边距,滚动条和边框大小(注意,不包括外边距). 以下4个属性可以获取 ...
- LayoutInflater.inflate()方法两个参数和三个参数
转载请标明出处:https://www.cnblogs.com/tangZH/p/7074853.html 很多人都用过LayoutInflater(布局填充器) 对于我来说通常使用下面两种:Lay ...
随机推荐
- html笔记第一天
快速生成标签有序ol>li*3无序ul>(li>a{新闻标题})*3定义列表 dl>(dt+dd)*3制作表格table>(tr>td*5)*6pading:3个数 ...
- webpack配置非CMD规范的模块
一.前言 webpack在配置多页面开发的时候 ,发现用 import 导入 Zepto 时,会报 Uncaught TypeError: Cannot read property 'createEl ...
- JavaScript 功能类 Url.js
简书原文 这个类的主要目的是为了方便平时编码中的Url类型的数据操作 Github 全局名称 全局名称是由源码的最后一行代码确定的,默认为Url,如存在相同名称的对象会抛出异常: 可以通过 requi ...
- webpack 4.0 中 clean-webpack-plugin 的使用
其实 clean-webpack-plugin 很容易知道它的作用,就是来清除文件的. 一般这个插件是配合 webpack -p 这条命令来使用,就是说在为生产环境编译文件的时候,先把 build或d ...
- 最快效率求出乱序数组中第k小的数
题目:以尽量高的效率求出一个乱序数组中按数值顺序的第k 的元素值 思路:这里很容易想到直接排序然后顺序查找,可以使用效率较高的快排,但是它的时间复杂度是O(nlgn),我们这里可以用一种简便的方法,不 ...
- [Swift]LeetCode105. 从前序与中序遍历序列构造二叉树 | Construct Binary Tree from Preorder and Inorder Traversal
Given preorder and inorder traversal of a tree, construct the binary tree. Note:You may assume that ...
- [Swift]LeetCode245.最短单词距离 III $ Shortest Word Distance III
This is a follow up of Shortest Word Distance. The only difference is now word1 could be the same as ...
- Linux 遭入侵,挖矿进程被隐藏排查记录
今天来给大家分享下这两天遇到的一个问题,服务器被挖矿了,把我的排查记录分享下,希望能帮到有需要的同学. 问题原因 多台服务器持续告警CPU过高,服务器为K8s的应用节点,正常情况下CPU使用率都挺低的 ...
- idea设置代码颜色主题(同Sublime Text 3的代码颜色一样)
1.下载主题的网址:http://color-themes.com,主题种类多,总有适合你的主题.在这个网址下载的主题是jar文件,直接导入,如下图file->import Setting,找 ...
- python3安装sklearn机器学习库
安装sklearn需要的库请全部在万能仓库下载: http://www.lfd.uci.edu/~gohlke/pythonlibs/#scipy http://www.lfd.uci.edu/~go ...