三个案例带你看懂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的根布局很特殊,其实不然。
OK,以上就是对LayoutInflater中inflate方法的一个简单介绍,希望能够帮助到还没弄懂这个的小伙伴。
以上。
三个案例带你看懂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,近两年才流行起来的超轻量级虚拟机,它可以让你轻松完成持续集成.自动交付 ...
- Android编程之LayoutInflater的inflate方法详解
LayoutInflater的inflate方法,在fragment的onCreateView方法中经常用到: public View onCreateView(LayoutInflater infl ...
- Android编程之LayoutInflater的inflate方法具体解释
LayoutInflater的inflate方法,在fragment的onCreateView方法中经经常使用到: public View onCreateView(LayoutInflater in ...
- Android编程之LayoutInflater的inflate方法实例
假设你不关心其内部实现,仅仅看怎样使用的话,直接看这篇就可以. 接上篇,接下来,就用最最简单的样例来说明一下: 用两个布局文件main 和 test: 当中,main.xml文件为: <?xml ...
- 一篇带你看懂Flutter叠加组件Stack
注意:无特殊说明,Flutter版本及Dart版本如下: Flutter版本: 1.12.13+hotfix.5 Dart版本: 2.7.0 Stack Stack组件可以将子组件叠加显示,根据子组件 ...
随机推荐
- ECSHOP:首页实现显示子分类商品,并实现点击Tab页切换分类商品
例子:首页实现显示子分类商品,并实现点击Tab页切换分类商品(非AJAX) 开始: 1. 打开调试开关 文件地址:include/cls_template.php 找到 : functi ...
- Entity Framework中的Migration问题
1.自从用上了Entity Framework(简称EF),妈妈再也不用担心我要写那么复杂的SQL语句了! 这是微软新一代的ORM工具,它能够将数据库的表中的记录映射成为程序中的一个对象,当然也能够将 ...
- 在windows10+word2010中完美使用北大方正word公式输入法总结
如果在安装输入法时遇到了无法安装的情况,请首先百度下VC运行库安装下(32位64位都安就是),然后安装北大方正word公式输入法,此时不会再提示无法安装,接着(关键)在word应用程序图标右键-> ...
- HDU 5624 KK's Reconstruction 最小生成树
题意:这是bc round 71 div 1 的 1004 直接去看中文题意 分析: 首先,一种合法方案对应了原图的一棵生成树. 我们知道,最小生成树有一个性质是最大边最小. 因此,我们可以枚举生成树 ...
- Mongo DB 安装-及分布式集群部署(初稿)
一.安装步骤, 1, 下载最新的Mongo DB数据库:http://www.mongodb.org/downloads?_ga=1.44426535.2020731121.1421844747\ 下 ...
- android和ios的系统特性区别
1. 删除:android是长按,ios为滑动/或者进入编辑模式 2. android:应用内返回键,保证用户停留在应用程序中:硬件返回键可以让用户退出应用程序 3. 剪切/粘贴/选择等文本操作 ...
- application/x-www-form-urlencoded等字符编码的解释说明
关于application/x-www-form-urlencoded等字符编码的解释说明 在Form元素的语法中,EncType表明提交数据的格式 用 Enctype 属性指定将数据回发到服务器时浏 ...
- jquery的全选/全不选/反选以及attr添加checked属性失败的解决办法
如下图: <head> <title></title> <style type="text/css"> div { border: ...
- 【JS】Advanced1:Object-Oriented Code
Object-Oriented Code 1. var Person = function (name) { this.name = name; }; Person.prototype.say = f ...
- HDU-4678 Mine 博弈SG函数
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4678 题意就不说了,太长了... 这个应该算简单博弈吧.先求联通分量,把空白区域边上的数字个数全部求出 ...