inflate()方法详解和源码分析
在开发中,我们经常需要使用到LayoutInflater,通过该对象的inflate()方法,将一个layout布局文件实例化为View对象。
关于LayoutInflater对象的获取,参考博文:
http://blog.csdn.net/ruancoder/article/details/51760942
今天主要对inflate()方法的使用和源码进行分析。
(1).inflate()方法的使用
在实际使用中,我们一般会用到inflate的以下两个重载方法。
方法一:
public View inflate(int resource, ViewGroup root) {}
方法二:
public View inflate(int resource, ViewGroup root, boolean attachToRoot) {}
其中方法一最为常见。
常见使用案例一:
View myView = LayoutInflater.from(context).inflate(R.layout.my_view, null);
将布局文件/res/layout/my_view.xml实例化为myView对象。
常见使用案例二:
ViewGroup viewRoot;
LayoutInflater.from(context).inflate(R.layout.my_view, viewRoot);
将布局文件/res/layout/my_view.xml实例化的View对象添加到viewRoot布局中。
那么方法一与方法二有什么区别呢?
进入方法一的源码,我们会发现内部调用的其实就是方法二,只是将方法二的第3个参数设为“root != null”。
public View inflate(int resource, ViewGroup root) {return inflate(resource, root, root != null);
}
方法二中的参数和返回值释义:
参数:
resource:需要实例化的布局资源id。
root:ViewGroup类型视图组对象
attachToRoot:是否将resource实例化后的View添加到参数root中。
返回值:
如果root为空,直接返回resource实例化后的View对象;
如果root不为空,attachToRoot为true,将resource实例化为view对象,忽略view的最外层视图在xml布局中定义的属性,将view添加到root中,并将root返回。
如果root不为空,attachToRoot为false,将resource实例化为view对象,为view的最外层视图设置其在xml布局中定义的属性,并将view对象返回。
(2).inflate()方法的源码分析
进入inflate()方法内部。
public View inflate(int resource, ViewGroup root, boolean attachToRoot) {final Resources res = getContext().getResources();// 根据layout resource id,获取该布局的XmlResourceParser对象final XmlResourceParser parser = res.getLayout(resource);try {return inflate(parser, root, attachToRoot);} finally {parser.close();}
}
从方法内部可以看到,LayoutInflater使用的是pull解析器来解析xml布局文件的。获取到布局resource的XmlResourceParser对象后,接着进入下一个方法。
public View inflate(XmlPullParser parser, ViewGroup root, boolean attachToRoot) {// ...// attrs是传入的布局layout在xml文件里面设置的属性集合final AttributeSet attrs = Xml.asAttributeSet(parser);// 将ViewGroup类型的参数root赋值给resultView result = root;// temp是传入的参数resource的根布局Viewfinal View temp = createViewFromTag(root, name, inflaterContext, attrs);ViewGroup.LayoutParams params = null;// 实例化temp视图内的所有子视图rInflateChildren(parser, temp, attrs, true);if (root != null) {// 根据attrs属性集,创建布局参数paramsparams = root.generateLayoutParams(attrs);// 如果temp不需要添加到root中,那么为temp设置布局参数paramsif (!attachToRoot) {temp.setLayoutParams(params);}}if (root != null && attachToRoot) {// 将temp添加到root中,并使用布局参数paramsroot.addView(temp, params);}if (root == null || !attachToRoot) {// 将temp赋值给result(在此之前,result==root)result = temp;}// ...return result;
}
该方法是inflate()的关键,这里只抽取了需要关注的核心代码。
最开始,定义方法的返回值result,将参数root赋值给result,实例化参数resource赋值给temp。
接下来进入判断条件。
当root!=null时,根据resource的最外层view在xml中定义的的属性,创建布局参数params。如果!attachToRoot,为temp设置布局参数params。
当root!=null&&attachToRoot,将temp添加到root中,并使用上面创建的布局参数params。
当root==null||!attachToRoot,将temp赋值给result。
最后,将result返回。
逻辑看起来较繁琐,简单点可以这么理解。
只要root==null,无视attachToRoot的值,创建temp对象,返回temp。
当root!=null时,分两种情况。一,attachToRoot==true,将temp添加到root中,并使用布局参数params,返回root。二,attachToRoot==false,为temp设置布局参数params,返回temp。
(3).inflate()方法代码示例
在上面对inflate(int resource, ViewGroup root, boolean attachToRoot)方法的源码分析中,关于参数和返回值及其中的逻辑不难理解,主要是方法内是否为temp设置布局参数有些难以理解。下面使用代码示例进行说明。
创建MainActivity,并设置界面布局activity_main.xml。
<?xml version="1.0" encoding="utf-8"?>
<LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"android:id="@+id/layout"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"/>
新建一个textview.xml。这里故意给TextView的layout_width和layout_height设定了固定数值,并添加layout_gravity属性。方便后面看出差异。
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="230dp"android:layout_height="80dp"android:layout_gravity="center_horizontal"android:background="#999999"android:text="blog.csdn.net/ruancoder"android:textColor="#ffffff"android:textSize="18sp"/>
在MainActivity的onCreate()方法中,添加如下代码。
<pre name="code" class="java">package net.csdn.blog.ruancoder;import android.app.Activity;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;public class MainActivity extends Activity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);ViewGroup root = (ViewGroup) findViewById(R.id.layout);View textView = LayoutInflater.from(this).inflate(R.layout.textview, null);root.addView(textView);}
}
运行效果图一: 然后,将onCreate()方法中的代码修改为如下:
ViewGroup root = (ViewGroup) findViewById(R.id.layout);
LayoutInflater.from(this).inflate(R.layout.textview, root, true);
或
ViewGroup root = (ViewGroup) findViewById(R.id.layout);
View textView = LayoutInflater.from(this).inflate(R.layout.textview, root, false);
root.addView(textView);
两种方式中的任意一种。
然后再看运行效果。
运行效果图二:
从图一的显示效果可以看出,我们为TextView设定的layout属性都失去了作用。而在图二中,这三个layout属性都正常显示出来了。
inflate()方法详解和源码分析相关推荐
- 并发编程五:java并发线程池底层原理详解和源码分析
文章目录 java并发线程池底层原理详解和源码分析 线程和线程池性能对比 Executors创建的三种线程池分析 自定义线程池分析 线程池源码分析 继承关系 ThreadPoolExecutor源码分 ...
- 史上最详细的ConcurrentHashMap详解--源码分析
ps.本文所有源码都是基于jdk1.6 首先说明一点,ConcurrentHashMap并不是可以完全替换Hashtable的,因为ConcurrentHashMap的get.clear函数是弱一致的 ...
- SpringBoot入门详解源码分析
注:文章内容来自于黑马的虎哥,个人感觉写的挺好的,所以只是做了简单整理,我只是文章的搬运工! # 0.学习目标 - 了解SpringBoot的作用 - 掌握java配置的方式 - 了解SpringBo ...
- python列表两两相减_用Python做打字软件,让你的打字快如闪电!附超详解和源码链接
版本正在更新--,目前1.3.2 项目结果 GIF制作十分粗劣,自己看着都揪心,不过基本看清楚了 详细解释 下面我会详细解释一下,如果不看,就不看吧,直接向下看源码,传送门 基本结构+标题标签+提示+ ...
- 桌面便签程序的实现详解和源码 (下)
来自:http://blog.csdn.net/silenceburn/article/details/6094705 在上半部分中,已经实现了一个可以运行的widget,但是没有任何业务功能, 因此 ...
- 桌面便签程序的实现详解和源码 (上)
来自:http://blog.csdn.net/silenceburn/article/details/6093074 桌面便签软件是android上常用软件的一种,比如比较早的Sticky Note ...
- 让你的打字快如闪电!用Python做打字软件,附超详解和源码链接
- 特征选择方法详解Part2-卡方检验、互信息(Mutual Information)
Content 1. 单变量分析 1.1 卡方检验 1.1.1 原理 1.1.2 使用示例 1.2 互信息(Mutual Information) 1.2.1 原理 1.2.1.1 互信息(Mutua ...
- C#高级编程——C#扩展方法+接口,定义统一的搜索接口,基于Unity(三)——图文详解加源码
C#高级编程--C#扩展方法+接口,定义统一的搜索接口,基于Unity(三)--图文详解加源码 前言
- aes js加密php解密实例,基于PHP和JS的AES相互加密解密方法详解(CryptoJS)_PHP_JS_AES源码...
[实例简介] 基于PHP和JS的AES相互加密解密方法详解(CryptoJS)_PHP_JS_AES源码 [实例截图] [核心代码] 基于PHP和JS的AES相互加密解密方法详解(CryptoJS)_ ...
最新文章
- Failed to load JavaHL Library(windows和mac)
- 选择性模糊及其算法的实现。
- mysql删除重复的判断_MySQL中查询、删除重复记录一共有多少种方法?
- Linux学习系列之Nginx调优实战
- OSGI嵌入jetty应用服务器
- 论文学习5-NODE2BITS: Compact Time- and Attribute-aware Node Representations for User Stitching
- 天线效应产生原因及解决办法
- 精美教师说课试讲教学通用PPT模板
- Js 嵌套if选择结构
- .NET连接IMB DB2数据库的一些问题及最终完美解决方案!
- 全球与中国高效无气油漆喷涂机市场深度研究分析报告
- 体验卓越品质 新贵Whql认证鼠标
- Android新浪微博授权提示:文件不存在 C8998 的终极解决方法
- 299. 猜数字游戏 js实现
- java 中利用subString 截取字符串中第三个/后面的内容,并将/用代替
- JS—随机三个0-9不重复的随机数
- Docker基础(上)
- 将两个或多个数组进行合并
- 计算机毕业设计Java企业员工工资管理系统
- 交叉熵损失函数(Cross Entropy Loss)
热门文章
- 使用session验证输入的验证码是否正确
- [打新技巧]打新股产品跷跷板定律
- tf.train.Saver()
- android电脑局域网传输方案,通过WiFi文件传输在Android和PC之间传输文件 | MOS86
- python画布组件_Python Tkinter 画布(Canvas)
- 人可以活很多次,但是七年就是一辈子
- Nmap的下载与基本命令运用
- 计算机中 空间局限性(Spatial Locality)与时间局限性(Temporal Locality)
- Python AngryBirds完整代码+讲解
- DTCMS 栏目调用方法