View inflate方法和LayoutInflater inflate方法的区别详解
原创文章,转载请注明出处:http://www.cnblogs.com/baipengzhan/p/6257510.html
我们在Android开发中,对于将布局填充成View对象,最常用的两种办法是:View类的方法inflate和LayoutInflater类的inflate方法,
今天有朋友问到这两种填充方法的区别,就查看了一下两者的区别,写成文章,以方便有需要的人。
首先我们要清楚两者大致的区别,之后我们再来慢慢看两者具体的不同之处。
LayoutInflater类的inflate方法适用于所有需要进行布局填充的场景,是Android中专门进行布局填充的方法,Android中其他需要
使用布局填充的地方,都会调用本方法,而不是View类中的inflate方法。该方法不是静态方法,需要先创建LayoutInflater类的对象
才能调用。
View类中的inflate方法内部包裹了LayoutInflater类的inflate方法,这个方法是一个静态方法,不需要创建View类的对象,直接使用
View类名调用,相比上一种方法是一种简便方法。但很明显,这个方法不如上一个方法功能强大。
若是您只想大概了解两者的区别,您读到这里已经足够了,下面的分析较为详细,请根据您的需要阅读下面的内容。
现在我们开始慢慢的研究两者具体的不同之处。
因为LayoutInflater类的inflate方法是所有布局填充方法的基石,我们先来看看这个方法吧。
我们从Google官方的SDK中的定义入手,得到比较标准的概念。
关于LayoutInflater类
该类是一个抽象类,继承自Object,存在于android.view包下。接下来我们只看和本文相关的内容,
不会再做过多的扩展。
以下是SDK中的叙述:
Instantiates a layout XML file into its corresponding View objects. It is never used directly. Instead, use getLayoutInflater() or getSystemService(String) to retrieve a standard LayoutInflater instance that is already hooked up to the current context and correctly configured for the device you are running on. For example:
LayoutInflater inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
To create a new LayoutInflater with an additional LayoutInflater.Factory for your own views, you can use cloneInContext(Context) to clone an existing ViewFactory, and then call setFactory(LayoutInflater.Factory) on it to include your Factory.
For performance reasons, view inflation relies heavily on pre-processing of XML files that is done at build time. Therefore, it is not currently possible to use LayoutInflater with an XmlPullParser over a plain XML file at runtime; it only works with an XmlPullParser returned from a compiled resource (R.something file.)
翻译和阐述:
LayoutInflater类的作用是,将xml布局文件实例化为它对应的View对象。这个类不能直接使用,也就是不能直接调用其中的成员。一般,我们通过getLayoutInflater()方法或者 getSystemService(String)
方法来获得该类的实例,通过以上两个方法获得的LayoutInflater类实例,已经和当前的上下文关联起来,并且已经正确配置在当前程序运行的设备上。我们顺便说一下这两个获得实例的方法:getLayoutInflater()方法,
并不是上下文的方法,Activity类有这个方法,不需要传入参数,在Activity中直接调用即可。Fragment类也有这个方法,但是需要传入一个Bundle对象作为参数。可以看到,通过该方法获得的LayoutInflater类对象
和上下文环境相配合。getSystemService(String)方法是Context的方法,需要传入Context的成员变量作为参数,获得相应的对象,要获得LayoutInflater对象,需要传入Context.LAYOUT_INFLATER_SERVICE
以上介绍的LayoutInflater类是Android系统为我们提供的通用类,如果我们想要为我们的View对象创建专用的LayoutInflater类,则可以用到LayoutInflater.Factory ,这是一个LayoutInflater类内部的接口,通过
工厂设计模式可以使我们获得定制的专用LayoutInflater类。我们可以使用cloneInContext(Context)来克隆一个已经存在的ViewFactory,然后调用setFactory(LayoutInflater.Factory)方法,将我们创建好的
工厂包括进来。在这里我大概说明一下这段话的意思和作用:当我在一个上下文环境中创建好了一个LayoutInflater工厂之后,我们又想在另一个上下文环境中使用这个LayoutInflater工厂,那该怎么办?这里说的一种方法
是,我们在当前上下文环境中,使用LayoutInflater类对象调用cloneInContext(Context)方法,其中的参数填写新上下文对象,因为我们要在新的上下文环境中使用。然后接着调用setFactory(LayoutInflater.Factory)方法,
其中的参数就是我们目前创建的LayoutInflater工厂。这样创建完成后,我们在新上下文环境中,就可以调用目前上下文环境中绑定了LayoutInflater工厂的LayoutInflater类对象了。关于这里的更详细用法在本文中就不更多阐述了,有兴趣的朋友请参看我的另一篇文章。
xml文件在创建阶段的前处理过程严重影响View对象填充阶段的性能(进而影响整体软件的性能),这是因为inflate方法内部使用的pull解析,若是xml文件在进行填充之前已经被xml解析了,那么inflate方法在使用时就非常轻松,否则会非常困难。因此,我们不会使用LayoutInflater类处理普通的xml文件,而是用来处理已经编译的xml文件,例如R.··········,这样的xml文件会返回一个已经解析了xml文件的pull解析器,而普通的xml文件返回的解析器则不然。更详细的内容请参看我的另一篇文章。
好啦,通过以上介绍,我们大概对LayoutInflater类有了一个大概了解,之后我们来看以下这个类中的4个重载的inflate方法应该如何使用。
这4个方法中,有两个是通过XmlPullParser作为数据来源创建view对象,剩下两个就是我们平时常用的两个通过resource目录下的文件作为数据来源的方法。
前两个方法在此我们不做详细介绍,这两个方法我们平时工作根本不会用,但是Android源文件中则大量使用,后边我们详细介绍的方法内部就是用前两种实现的。今后我会在其他文章中细细的分析这两个方法的使用,希望能帮助到感兴趣的朋友。
接下来我们就看看下边两个常用方法的使用。
三个参数的方法
public View inflate (int resource, ViewGroup root, boolean attachToRoot)
Inflate a new view hierarchy from the specified xml resource. Throws InflateException if there is an error.
从指定的xml文件生成新的view视图关系。出现错误时,抛出InflateException异常。
参数分析
第一个参数,就是我们要填充的xml文件
第二个参数,这个要和第三个参数有关系,大家慢慢看。若是第三个参数为true,那么第二个参数的意义是,从第一个参数填充成的view对象的父控件;若是第三个参数为false,那么第二个参数的意义是,
可以为第一个参数生成的view对象的根布局提供一系LayoutParams参数的控件。
第三个参数,从第一个参数填充成的view对象是否要附着到第二个参数指定的空间上作为子控件。
说明:第一个参数不需多说,我们一般就从resource目录下找到我们要填充的布局文件即可,切不可用普通的xml文件进行填充,除非我们自己做好了相应的xmlpullparser。
若第二个参数为null,也就是我们不指定父控件,那么新生产的view对象的根布局的某些参数会失效,比如Layout_width和Layout_height会失效,这个大家可以做实验尝试,无论第三个参数是什么。
关于该方法的使用只介绍到这里,更详细的用法请查找专门讲解该方法的文章。
返回:若提供了root,且第三个参数为true,则返回root作为根布局,否则,返回填充出的view对象的根布局作为根布局。
两个参数的用法
public View inflate (int resource, ViewGroup root)
从指定的xml文件生成新的view视图关系。出现错误时,抛出InflateException异常。
参数分析:
第一个参数,要填充的xml文件。
第二个参数,生成的view对象的父控件。同样该参数可以为null。若提供了root,则返回root作为根布局,否则,返回填充出的view对象的根布局作为根布局。
该方法内部调用了三个参数的方法,请看下面源码:
public View inflate(@LayoutRes int resource, @Nullable ViewGroup root) {
return inflate(resource, root, root != null);
}
两个参数方法的使用完全和三个参数方法相对应,在此不做更多介绍。
关于View类的inflate方法
public static View inflate (Context context, int resource, ViewGroup root)
Inflate a view from an XML resource. This convenience method wraps the LayoutInflater class, which provides a full range of options for view inflation.
将一个xml资源填充成一个view对象。这个简便的方法包裹了LayoutInflater类,后者提供了view对象填充的所有方法。
参数分析:
第一个参数,上下文
第二个参数,要填充的xml资源
第三个参数,填充成的view对象的根布局
说明,从SDK解释中的“convenience”一词中,我们就可以看到View类中inflate的主要特点,就是简便。它将LayoutInflater类封装,且是一个静态方法,便于调用。
以下为源码:
public static View inflate(Context context, @LayoutRes int resource, ViewGroup root) {
LayoutInflater factory = LayoutInflater.from(context);
return factory.inflate(resource, root);
}
可以看到其内部也就是调用了LayoutInflater两个参数的inflate方法而已,已经在上面介绍过了,不再赘述。
好啦,那我们总结一下吧:
LayoutInflater类的inflate方法适用于所有需要进行布局填充的场景,是Android中专门进行布局填充的方法,Android中其他需要
使用布局填充的地方,都会调用本方法,而不是View类中的inflate方法。该方法不是静态方法,需要先创建LayoutInflater类的对象
才能调用。
View类中的inflate方法内部包裹了LayoutInflater类的inflate方法,这个方法是一个静态方法,不需要创建View类的对象,直接使用
View类名调用,相比上一种方法是一种简便方法。但很明显,这个方法不如上一个方法功能强大。
View inflate方法和LayoutInflater inflate方法的区别详解的更多相关文章
- RequestDispatcher.forward() 方法和HttpServletResponse.sendRedirect()方法的区别
RequestDispatcher.forward() 方法和HttpServletResponse.sendRedirect()方法的区别 先贴一段代码 public void logon(Http ...
- synchronized 修饰在 static方法和非static方法的区别
Java中synchronized用在静态方法和非静态方法上面的区别 在Java中,synchronized是用来表示同步的,我们可以synchronized来修饰一个方法.也可以synchroniz ...
- Java中synchronized 修饰在static方法和非static方法的区别
[问题描述]关于Java中synchronized 用在实例方法和对象方法上面的区别 [问题分析]大家都知道,在Java中,synchronized 是用来表示同步的,我们可以synchronized ...
- length属性,length()方法和size()的方法的区别
一.java 1.length属性是针对Java中的数组来说的,要求数组的长度可以用其length属性: 2.length()方法是针对字符串来说的,要求一个字符串的长度就要用到它的length()方 ...
- static方法和非static方法的区别
●生命周期(Lifecycle):静态方法(Static Method)与静态成员变量一样,属于类本身,在类装载的时候被装载到内存(Memory),不自动进行销毁,会一直存在于内存中,直到JVM关闭. ...
- querySelectorAll 方法和 getElementsBy 系列方法的区别
本文是我在知乎上的一个回答:http://www.zhihu.com/question/24702250/answer/28695133 ————— 下面是正文 ————— 1. W3C 标准quer ...
- jQUery中的$(document).ready()方法和window.onload()方法的区别
1.常规的Javascript代码中,通常使用window.onload方法 window.onload = function(){//代码} 2.jquery中,则使用$(document).rea ...
- length属性、length()方法和size()的方法的区别
JAVA 1. length属性是针对Java中的数组来说的,要求数组的长度可以用其length属性: 2.length()方法是针对字符串来说的,要求一个字符串的长度就要用到它的length()方法 ...
- 基于jquery的has()方法以及与find()方法以及filter()方法的区别详解
has(selector选择器或DOM元素) 将匹配元素集合根据选择器或DOM元素为条件,检索该条件在每个元素的后代中是否存在,将符合条件的的元素构成新的结果集. 下面举一个例子: <ul& ...
随机推荐
- Android设备 cocos2dx 骨骼动画注册事件播放音效,退到后台再返回黑屏问题
最近遇到一个cocos2dx 骨骼动画注册事件播放音效,在骨骼动画播放的时候,按HOME键退到桌面,再次打开游戏的时候,会黑屏. 解决办法如下,可能不是太完美,至少解决了大部分问题. 1.在org.c ...
- js字符串比较
1,大写字母小于小写字母 a='ang',b='Zh' 那么a>b 2,可以使用字符串的toUpperCase()/toLowerCase()方法不区分字母的大小写. a.toUpperCase ...
- Cacti添加threshold、monitor和setting
Cacti版本:Version 0.8.8b 一.插件介绍: monitor:通过简单明了的图标提供服务器的运行状态 settings:给不同的插件提供一些共用的信息,如邮件信息,dns信息thold ...
- App Store审核指南(中文版)2010版
前言 感谢您付出宝贵的才华与时间来开发iOS应用程程序.从职业与报酬的角度而言,这对于成千上万的开发员来说一直都是一项值得投入的事业.我们希望帮助您加入这个成功的组织.这是我们首次发布<应用程序 ...
- JFrome 登陆/注册/回显无数据库连接小程序
当离开RCP插件区重新回顾一下JFrame窗口程序的标签.页面间的跳转. 完成一个登陆.注册界面.(界面完成后练习输入输出流,将前台的注册信息保存到一个文件夹下的.txt文件中) 首先向通过JFram ...
- hive 桶相关特性分析
1. hive 桶相关概念 桶(bucket)是指将表或分区中指定列的值为key进行hash,hash到指定的桶中,这样可以支持高效采样工作. 抽样( sampling )可以在全体数 ...
- 【行为型】TemplateMethod模式
模板方法意图是为算法定义好骨架结构,并且其中的某些步骤延迟到子类实现.该模式算是较为简单的一种设计模式.在实际中,应用也较为频繁.模式的类关系图参考如下: 模式的编码结构参考如下: namespace ...
- traceroute命令
traceroute指令让你追踪网络数据包的路由途径,预设数据包大小是40Bytes,用户可另行设置. 通过traceroute我们可以知道信息从你的计算机到互联网另一端的主机是走的什么路径.当然每次 ...
- 前端面试题第一波,要offer的看过来~
一.HTML常见题目 01.Doctype作用?严格模式与混杂模式如何区分?它们有何意义? 02.HTML5为什么只需要写<!DOCTYPE HTML>? 03.行内元素有哪些?块级元素有 ...
- 在安装包运行时指定Component的安装路径
Basic MSI工程类型中如果实现动态指定安装路径的功能,下面介绍的方法也适用于InstallScript MSI工程. 1. 在Setup Design中找到相对应的Component. 2. 点 ...