原创文章,转载请注明出处: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方法的区别详解的更多相关文章

  1. RequestDispatcher.forward() 方法和HttpServletResponse.sendRedirect()方法的区别

    RequestDispatcher.forward() 方法和HttpServletResponse.sendRedirect()方法的区别 先贴一段代码 public void logon(Http ...

  2. synchronized 修饰在 static方法和非static方法的区别

    Java中synchronized用在静态方法和非静态方法上面的区别 在Java中,synchronized是用来表示同步的,我们可以synchronized来修饰一个方法.也可以synchroniz ...

  3. Java中synchronized 修饰在static方法和非static方法的区别

    [问题描述]关于Java中synchronized 用在实例方法和对象方法上面的区别 [问题分析]大家都知道,在Java中,synchronized 是用来表示同步的,我们可以synchronized ...

  4. length属性,length()方法和size()的方法的区别

    一.java 1.length属性是针对Java中的数组来说的,要求数组的长度可以用其length属性: 2.length()方法是针对字符串来说的,要求一个字符串的长度就要用到它的length()方 ...

  5. static方法和非static方法的区别

    ●生命周期(Lifecycle):静态方法(Static Method)与静态成员变量一样,属于类本身,在类装载的时候被装载到内存(Memory),不自动进行销毁,会一直存在于内存中,直到JVM关闭. ...

  6. querySelectorAll 方法和 getElementsBy 系列方法的区别

    本文是我在知乎上的一个回答:http://www.zhihu.com/question/24702250/answer/28695133 ————— 下面是正文 ————— 1. W3C 标准quer ...

  7. jQUery中的$(document).ready()方法和window.onload()方法的区别

    1.常规的Javascript代码中,通常使用window.onload方法 window.onload = function(){//代码} 2.jquery中,则使用$(document).rea ...

  8. length属性、length()方法和size()的方法的区别

    JAVA 1. length属性是针对Java中的数组来说的,要求数组的长度可以用其length属性: 2.length()方法是针对字符串来说的,要求一个字符串的长度就要用到它的length()方法 ...

  9. 基于jquery的has()方法以及与find()方法以及filter()方法的区别详解

    has(selector选择器或DOM元素)   将匹配元素集合根据选择器或DOM元素为条件,检索该条件在每个元素的后代中是否存在,将符合条件的的元素构成新的结果集. 下面举一个例子: <ul& ...

随机推荐

  1. MySQL存储过程(一)

    1.1 CREATE  PROCEDURE (创建) CREATE PROCEDURE存储过程名 (参数列表) BEGIN SQL语句代码块 END 注意: 由括号包围的参数列必须总是存在.如果没有参 ...

  2. readonly 与 const

    readonly MSDN定义:readonly 关键字是可以在字段上使用的修饰符.当字段声明包括 readonly 修饰符时,该声明引入的字段赋值只能作为声明的一部分出现,或者出现在同一类的构造函数 ...

  3. c# 学习笔记(三)

    程序集程序集的私有部署 不用在注册表中注册组件卸载只需要从文件系统中删除他即可 共享程序集和GAC 只有强命名程序集能被添加到GAC中程序集数据签名只需在安装到GAC时检查一次 GAC内的并肩执行GA ...

  4. UITextView textViewShouldEndEditing

    最近做到UITextView, 在取消键盘事件上我以为和UITextField差不多,于是我这样写: UITextView *textView = [[UITextView alloc] initWi ...

  5. Asp.net 主题 【1】

    页面中默认的显示样式太朴素,一页一页的设置控件的显示样式效率又太低,主题和皮肤则提供了一种高效的设计方案.   一.添加主题 二.添加皮肤文件(.skin): 在皮肤文件中添加如下代码 <asp ...

  6. 重新开始学习javase_对象的摧毁

    一.概述(转:@深入理解Java虚拟机:JVM高级特性与最佳实践(最新第二版) ) 经过半个世纪的发展,内存的动态分配与内存回收技术已经相当成熟,一切看起来都进入了“自动化”时代,那为什么我们还要去了 ...

  7. [转载]Java synchronized详解

    在编写一个类时,如果该类中的代码可能运行于多线程环境下,那么就要考虑同步的问题.在Java中内置了语言级的同步原语--synchronized,这也大大简化了Java中多线程同步的使用.我们首先编写一 ...

  8. Direct2D 加载位图

    说明: 通过WIC从文件加载位图. 可缩放后加载到内存. 源码: HRESULT LoadImageFormFile( IWICImagingFactory *pWicFactory, ID2D1Re ...

  9. ASP.NET MVC中的模型绑定

    模型绑定的本质   任何控制器方法的执行都受action invoker组件(下文用invoker代替)控制.对于每个Action方法的参数,这个invoker组件都会获取一个Model Binder ...

  10. AutoIt3初探(1)

    AutoIt3可实现系统操作,键盘鼠标模拟,是自动化测试的一个好工具. 这个是在线帮助文档,http://www.jb51.net/shouce/autoit/ 需要先下载一个autoIt安装,然后将 ...