一、获取LayoutInflater的三种方法

1、

LayoutInflater layoutInflater = (LayoutInflater) MainActivity.this.getSystemService(Context.LAYOUT_INFLATER_SERVICE);

2、

LayoutInflater layoutInflater = LayoutInflater.from(MainActivity.this);

3、

LayoutInflater layoutInflater = MainActivity.this.getLayoutInflater();

其实查看它们的源码就会发现,后两种方法最终也还是调用第一种方法的context.getSystemService(Context.LAYOUT_INFLATER_SERVICE)。不过查看第三种方法的源码要稍微绕一下,因为activity.getLayoutInflater(),其实是调用Window类的getLayoutInflater(),而这个是抽象类。根据这个类的注释,可以查看它的子类PhoneWindow,而这个是内部类,用开发工具是找不到这个类的,要手动去找。可以从sdk的文件目录下找,例如,我的是“D:\Android\Sdk\sources\android-23\com\android\internal\policy”。也可以直接在sdk目录下,搜索该类就行了。

其实View有一个静态的inflate方法,连LayoutInflater对象都帮你内部创建了。其方法源码如下:

    public static View inflate(Context context, @LayoutRes int resource, ViewGroup root) {
LayoutInflater factory = LayoutInflater.from(context);
return factory.inflate(resource, root);
}

 二、inflate方法的一些参数问题

以前是困惑于inflate方法的作用。现在是困惑于什么时候才传入ViewGroup对象和attachToRoot的取值。所以分析了一下源码。

当写ListView的Adapter时,总要在getView方法里调用inflate方法,例如:

convertView = LayoutInflater.from(mContext).inflate(R.layout.push_to_refresh_header, parent, false);

这个inflate方法的源码是:

    public View inflate(@LayoutRes int resource, @Nullable ViewGroup root, boolean attachToRoot) {
final Resources res = getContext().getResources();
if (DEBUG) {
Log.d(TAG, "INFLATING from resource: \"" + res.getResourceName(resource) + "\" ("
+ Integer.toHexString(resource) + ")");
} final XmlResourceParser parser = res.getLayout(resource);
try {
return inflate(parser, root, attachToRoot);
} finally {
parser.close();
}
}

这个时候传入的ViewGroup对象不为nullt,同时设置boolean attachToRoot为false。

而在动态添加布局的时候,我学到的是下面这种写法:

View refreshView = layoutInflater.inflate(R.layout.push_to_refresh_header, null);
linearLayout.addView(refreshView);

这个inflate方法的源码是:

    public View inflate(@LayoutRes int resource, @Nullable ViewGroup root) {
return inflate(resource, root, root != null);
}

这个时候传入的ViewGroup对象为null。

可以看到,当调用两个参数的inflate方法时,它会以ViewGroup对象不等于空的判断值为参数attachToRoot的值,并和之前的参数传到另一个带有三个参数的inflate方法。

最终都会调用下面这个inflate方法。这里我们只需关注ViewGroup root、boolean attachToRoot和返回值result就可以了,所以我把其它省略了。

     public View inflate(XmlPullParser parser, @Nullable ViewGroup root, boolean attachToRoot) {
synchronized (mConstructorArgs) {
         ......
 9 View result = root; try {
           ......
32
if (TAG_MERGE.equals(name)) {
              ......
40 } else {
// Temp is the root view that was found in the xml
final View temp = createViewFromTag(root, name, inflaterContext, attrs); ViewGroup.LayoutParams params = null; if (root != null) {
                ......
51 // Create layout params that match root, if supplied
params = root.generateLayoutParams(attrs);
if (!attachToRoot) {
// Set the layout params for temp if we are not
// attaching. (If we are, we use addView, below)
temp.setLayoutParams(params);
}
}
              ......
70
// We are supposed to attach all the views we found (int temp)
// to root. Do that now.
if (root != null && attachToRoot) {
root.addView(temp, params);
} // Decide whether to return the root that was passed in or the
// top view found in xml.
if (root == null || !attachToRoot) {
result = temp;
}
} }
         ......
return result;
}
}

在第9行可以看到返回值result的初始值是root。

然后整个方法就只有第79行的if语句会修改result。而条件就是root为null,或者attachToRoot为假。而这个temp在第42行可以找到初值。其实上面的注释已经告诉我们,temp是我们传入的布局文件中的根视图。

在Adapter的getView方法里,虽然传入的root不为null,但attachToRoot为false,所以返回值就是我们传入的布局文件中的根视图,用来为布局中的控件初始化和修改。而上面那种动态添加布局的方式,传入的root为null,也是如此。

那为什么getView方法不直接传进null呢?这个我没能从源码上找到为什么,只知道,当传进ViewGroup对象为null时,运行会报错,说Adapter为null,就是Adapter对象没有初始化。那如果传进了root,但令attachToRoot为true呢?也是会运行报错。

先看看第73行的if语句。它表示的是root不为null,同时attachToRoot为true时,就会把temp和它的布局参数添加到root中。

所以在上面那种情况中,root其实就是ListView,而在ListView的父类AdapterView中,其方法的注释声明了是不支持addView方法的,一旦调用就会报错。

而我上面动态添加布局的那种写法,也就可以替换成:

View refreshView = layoutInflater.inflate(R.layout.push_to_refresh_header, linearLayout);

把父布局的根视图传进去就可以了,它会自动生成attachToRoot的值为true。然后再把要添加的布局中的根视图添加到root中。

获取LayoutInflater对象的方法和inflate方法的一些参数问题的更多相关文章

  1. java 集合 HashSet 实现随机双色球 HashSet addAll() 实现去重后合并 HashSet对象去重 复写 HashCode()方法和equals方法 ArrayList去重

    package com.swift.lianxi; import java.util.HashSet; import java.util.Random; /*训练知识点:HashSet 训练描述 双色 ...

  2. jquery attr方法和prop方法获取input的checked属性问题

    jquery attr方法和prop方法获取input的checked属性问题   问题:经常使用jQuery插件的attr方法获取checked属性值,获取的值的大小为未定义,此时可以用prop方法 ...

  3. Java 如何重写对象的 equals 方法和 hashCode 方法

    前言:Java 对象如果要比较是否相等,则需要重写 equals 方法,同时重写 hashCode 方法,而且 hashCode 方法里面使用质数 31.接下来看看各种为什么. 一.需求: 对比两个对 ...

  4. Thread类的sleep()方法和对象的wait()方法都可以让线程暂停执行,它们有什么区别? 线程的sleep()方法和yield()方法有什么区别?

    Thread类的sleep()方法和对象的wait()方法都可以让线程暂停执行,它们有什么区别? sleep()方法(休眠)是线程类(Thread)的静态方法,调用此方法会让当前线程暂停执行指定的时间 ...

  5. Android HTTP实例 使用GET方法和POST方法发送请求

    Android HTTP实例 使用GET方法和POST方法发送请求 Web程序:使用GET和POST方法发送请求 首先利用MyEclispe+Tomcat写好一个Web程序,实现的功能就是提交用户信息 ...

  6. wait方法和sleep方法的区别

    一.概念.原理.区别 Java中的多线程是一种抢占式的机制而不是分时机制.线程主要有以下几种状态:可运行,运行,阻塞,死亡.抢占式机制指的是有多个线程处于可运行状态,但是只有一个线程在运行.      ...

  7. OC类的本质,深入探讨,load方法和initialize方法

    1:类的本质:类也是一种类,可以叫做类类,类对象,类类型: 2:类和对象在内存中分配问题(注意区分类的对象和类对象的概念) 类对象在内存中只有一份,且只加载一次,类对象中存放了类中定义的方法: 而成员 ...

  8. JAVA反射中的getFields()方法和getDeclaredFields ()方法的区别

    JAVA反射中的getFields()方法和getDeclaredFields ()方法的区别   关于获取类的字段有两种方式:getFields()和getDeclaredFields().我们先来 ...

  9. Junit 注解 类加载器 .动态代理 jdbc 连接池 DButils 事务 Arraylist Linklist hashset 异常 哈希表的数据结构,存储过程 Map Object String Stringbufere File类 文件过滤器_原理分析 flush方法和close方法 序列号冲突问题

    Junit 注解 3).其它注意事项: 1).@Test运行的方法,不能有形参: 2).@Test运行的方法,不能有返回值: 3).@Test运行的方法,不能是静态方法: 4).在一个类中,可以同时定 ...

随机推荐

  1. centos6.6-------DHCP服务配置

    一.为一个单一的网段提供地址服务 软件包:  dhcp配置文件:  /etc/dhcp/dhcpd.conf租约文件:     /var/lib/dhcpd/dhcpd.leases监听端口:     ...

  2. linux 套接字编程入门--Hello World

    下述代码是linux套接字编程的入门代码.分为服务端和客户端源码. 服务端代码的主要流程是绑定ip地址和端口号建立套接字,等待客户端发起访问.接受客户端请求之后,向客户端发送字符串"hell ...

  3. imageX批量安裝windows7

    以一臺電腦爲sample,安裝完成windows os及其全部update,安裝全部常用軟件,打印機驅動,網絡磁碟機等. 關閉安全控制"UAC"和"維護解決方案" ...

  4. OSG和osgearth显示中文(转载)

    osgEarth支持中文过程详解 OSG和osgearth显示中文 一.知识储备   要想很好的理解和解决这个问题,首先要了解什么是多字节和宽字节.说实话我之前也知道这两个字节到底有什么区别,只是简单 ...

  5. HDU-2573-Typing

    题目链接 http://acm.hdu.edu.cn/showproblem.php?pid=2573 这题把%s与gets()的输入法搞混了一直感觉没有错,就是找不出哪里错了, 题目思路不是很难. ...

  6. JS模板引擎:基于字符串拼接

    目的 编写一个基于字符串拼接的js模板引擎雏形,这里并不会提供任何模板与数据的绑定. 基本原理 Javascript中创建函数的方式有多种,包括: 1. var func = function () ...

  7. 我用Cocos2d-x模拟《Love Live!学院偶像祭》的Live场景(二)

    上一章分析了Live场景中各个元素的作用,这一章开始来分析最关键的部分——打击物件的实现. 上一章放出的视频很模糊,先来看一个清晰版的复习一下:http://www.bilibili.com/vide ...

  8. Flex 数据绑定

    Flex 数据绑定 <?xml version="1.0" encoding="utf-8"?> <s:Application xmlns:f ...

  9. Bootstrap入门(二十九)JS插件6:弹出框

    Bootstrap入门(二十九)JS插件6:弹出框 加入小覆盖的内容,像在iPad上,用于存放非主要信息 弹出框是依赖于工具提示插件的,那它也和工具提示是一样的,是需要初始化才能够使用的 首先我们引入 ...

  10. objectc中函数前的加号和减号

    看object-c中的代码里,函数(方法)前总有一个加号或者减号,不知道是什么意思,度娘了一下. http://zhidao.baidu.com/link?url=gw9-JR3bh0i7E_CHbr ...