上次讲到以下这么一段代码,这段代码的作用就是解析xml文件成为view并显示到屏幕上的。

 @Override
//设置contentview,也就是activity或fragment载入视图,即view的函数。接受的參数是资源id
public void setContentView(int layoutResID) {
//mContentParent是个ViewGroup ,这里mContentParent == null肯定是成立的
if (mContentParent == null) {
//成立后就会执行这一句话,从字面意思就能够看出,是安装解析器来着
installDecor();
} else {
mContentParent.removeAllViews();
}
//这一句话開始解析并初始化资源了
mLayoutInflater.inflate(layoutResID, mContentParent);
//取得对应的回调
final Callback cb = getCallback();
if (cb != null) {
//一旦有回调被调用了,就要通知视图改变
cb.onContentChanged();
}
}

纵观上面的一段代码,可能最实用的无非这么一句

 mLayoutInflater.inflate(layoutResID, mContentParent);

他解析了id为layoutResId的资源。

mLayoutInflater这个成员变量,说起这个东西。又是一堆废话要讲。大家千万不要嫌我啰嗦。由于终于我会回到一个很实用的主题。在阐述这个主题之前。这些“小知识”都是必备的,就比方说爱爱之前总要来点前戏对吧

假设你听说过Fragment,那么应该知道fragment中载入视图是通过类似

public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
super.onCreateView(inflater, container, savedInstanceState);
View layout = inflater.inflate(R.layout.main_activity_menu, null);
initLayouView(layout);
return layout;
}

这种代码实现的。

这就是inflate的作用。他就是用来解析xml并显示到屏幕的,至于解析的代码我这边就不多做阐述了,毕竟已经超越了我们的主题太远。我们还是看inflate是怎样给解析的xml分配内存。并加入到view上的吧!

这里是

v=source">LayoutInflater.java的源码

当中inflate函数的实如今这里:

    public View inflate(XmlPullParser parser, ViewGroup root, boolean attachToRoot) {
synchronized (mConstructorArgs) {
final AttributeSet attrs = Xml.asAttributeSet(parser);
mConstructorArgs[0] = mContext;
View result = root; try {
int type;
while ((type = parser.next()) != XmlPullParser.START_TAG &&
type != XmlPullParser.END_DOCUMENT) {
// Empty
} if (type != XmlPullParser.START_TAG) {
throw new InflateException(parser.getPositionDescription()
+ ": No start tag found!");
}
//这里取得XML标签名字,比方说LinearLayout
final String name = parser.getName(); if (TAG_MERGE.equals(name)) {
if (root == null || !attachToRoot) {
throw new InflateException("<merge /> can be used only with a valid "
+ "ViewGroup root and attachToRoot=true");
} rInflate(parser, root, attrs);
} else {
// 在此处创建视图,參数是前面取得的name,也就是说取得了LinearLayout開始new这个对象了! 第二个參数就是这个视图的属性
View temp = createViewFromTag(name, attrs); //下面的代码省略......

以上的代码中。注意这一行:

 View temp = createViewFromTag(name, attrs);

这一行就是通过解析tag来创建view的,这种方法的实现例如以下:

//这里的整个过程是:先推断是不是view,假设是的话。再取得属性值
View createViewFromTag(String name, AttributeSet attrs) {
if (name.equals("view")) {
name = attrs.getAttributeValue(null, "class");
} try {//这里的mFactory是一个叫做Factory的interface,在Inflater类构造的时候新建了mFactory对象
View view = (mFactory == null) ? null : mFactory.onCreateView(name,
mContext, attrs); if (view == null) {
if (-1 == name.indexOf('.')) {
view = onCreateView(name, attrs);
} else {
view = createView(name, null, attrs);
}
} //下面代码省略...

再关注里面的

                    view = createView(name, null, attrs);

这句话,正式開始创建了!

public final View createView(String name, String prefix, AttributeSet attrs)
throws ClassNotFoundException, InflateException {
//这里取得了xml的标签,比方说LinearLayout,这个构造器类是通过java的反射获取对象以及參数
Constructor constructor = sConstructorMap.get(name);
Class clazz = null; try {
if (constructor == null) {
// 这个是我们熟悉的类载入器。是另外一种初始化对象的方法(第一种是直接new出来)
clazz = mContext.getClassLoader().loadClass(
prefix != null ? (prefix + name) : name); if (mFilter != null && clazz != null) {
boolean allowed = mFilter.onLoadClass(clazz);
if (!allowed) {
failNotAllowed(name, prefix, attrs);
}
}
constructor = clazz.getConstructor(mConstructorSignature);
sConstructorMap.put(name, constructor);
} else {
// If we have a filter, apply it to cached constructor
if (mFilter != null) {
// Have we seen this name before?
Boolean allowedState = mFilterMap.get(name);
if (allowedState == null) {
// New class -- remember whether it is allowed
clazz = mContext.getClassLoader().loadClass(
prefix != null ? (prefix + name) : name); boolean allowed = clazz != null && mFilter.onLoadClass(clazz);
mFilterMap.put(name, allowed);
if (!allowed) {
failNotAllowed(name, prefix, attrs);
}
} else if (allowedState.equals(Boolean.FALSE)) {
failNotAllowed(name, prefix, attrs);
}
}
} Object[] args = mConstructorArgs;
args[1] = attrs;
//上面取得了view,在这里又取得了attrs,换句话说,既取得了对象(比方说LinearLayout),又取得了參数(比方说高度,宽度等等)
return (View) constructor.newInstance(args);//下面代码省略...

创建成功了!

LinearLayout具体解释三:LayoutInflater创建View过程分析的更多相关文章

  1. Js基础知识4-函数的三种创建、四种调用(及关于new function()的解释)

    在js中,函数本身属于对象的一种,因此可以定义.赋值,作为对象的属性或者成为其他函数的参数.函数名只是函数这个对象类的引用. 函数定义 // 函数的三种创建方法(定义方式) function one( ...

  2. 2019年6月14日 Web框架之Django_07 进阶操作(MTV与MVC、多对多表三种创建方式、前后端传输数据编码格式contentType、ajax、自定义分页器)

    摘要 MTV与MVC 多对多表三种创建方式 ajax ,前后端传输数据编码格式contentType 批量插入数据和自定义分页器 一.MVC与MTV MVC(Model View Controller ...

  3. Android使用默认样式创建View的几个姿势

    以下内容是分析安卓源码所得: 1: 使用默认样式创建View的方式, 源码文件 Button.Java  注:此文参考http://www.linzenews.com/ 中的内容所写,如侵删! 2: ...

  4. 使用Java代码来创建view

    使用Java代码来创建view 一.简介 需要了解的知识 二.方法 1)java代码创建view方法 * 1.先建view对象 View view= View.inflate(this, R.layo ...

  5. Django-多对多关系的三种创建方式-forms组件使用-cookie与session-08

    目录 表模型类多对多关系的三种创建方式 django forms 组件 登录功能手写推理过程 整段代码可以放过来 forms 组件使用 forms 后端定义规则并校验结果 forms 前端渲染标签组件 ...

  6. geotrellis使用(三)geotrellis数据处理过程分析

    之前简单介绍了geotrellis的工作过程以及一个简单的demo,最近在此demo的基础上实现了SRTM DEM数据的实时分析以及高程实时处理,下面我就以我实现的上述功能为例,简单介绍一下geotr ...

  7. Fixflow引擎解析(三)(模型) - 创建EMF模型来读写XML文件

    Fixflow引擎解析(四)(模型) - 通过EMF扩展BPMN2.0元素 Fixflow引擎解析(三)(模型) - 创建EMF模型来读写XML文件 Fixflow引擎解析(二)(模型) - BPMN ...

  8. VMware vSphere 服务器虚拟化之二十二桌面虚拟化之创建View Composer链接克隆的虚拟桌面池

    VMware vSphere 服务器虚拟化之二十二桌面虚拟化之创建View Composer链接克隆的虚拟桌面池 在上一节我们创建了完整克隆的自动专有桌面池,在创建过程比较缓慢,这次我们将学习创建Vi ...

  9. IOS程序创建view

    在IOS程序中创建view有六种方式 首先创建一个GLViewController类,继承UIViewController. 然后进入GLAppDelegate.m,在- (BOOL)applicat ...

随机推荐

  1. 大数据学习——spark-steaming学习

    官网http://spark.apache.org/docs/latest/streaming-programming-guide.html 1.1.  用Spark Streaming实现实时Wor ...

  2. Java EE - Servlet 3.0 和 Spring MVC

    Table of Contents 前言 基于 Java 的配置 ServletContainerInitializer 动态配置 DispatcherServlet 和 ContextLoaderL ...

  3. Python学习-day5 常用模块

    day5主要是各种常用模块的学习 time &datetime模块 random os sys shutil json & picle shelve xml处理 yaml处理 conf ...

  4. POJ 1609 Tiling Up Blocks

    Tiling Up Blocks Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 4675   Accepted: 1824 ...

  5. jsonp跨域请求发布出去

    最近在做运动城项目,这一个项目下面有多个子项目,如主数据项目,pos项目等.主数据项目的域名为www.topmall.com,POS项目的域名为pos.topmall.com.即两个项目的主域名相同, ...

  6. 【bzoj2729】[HNOI2012]排队 组合数学+高精度

    题目描述 某中学有 n 名男同学,m 名女同学和两名老师要排队参加体检.他们排成一条直线,并且任意两名女同学不能相邻,两名老师也不能相邻,那么一共有多少种排法呢?(注意:任意两个人都是不同的) 输入 ...

  7. HDU——1395 2^x mod n = 1(取模运算法则)

    2^x mod n = 1 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) To ...

  8. Zabbix实现短信报警设置(实战)

    配置环境: zabbix 2.2.15 1.配置示警媒介类型 此文件所在位置:/usr/lib/zabbix/alertscripts/ 必须拥有执行权限,并且改变所属用户和组 要修改此脚本的路径,需 ...

  9. 单线程实现并发——协程,gevent模块

    一 并发的本质 1 切换 2 保存状态 二 协程的概念 协程,又称微线程,纤程.英文名Coroutine.单线程下实现并发,用户从应用程序级别控制单线程下任务的切换,注意一定是遇到I/O才切. 协程的 ...

  10. bzoj 1185 [HNOI2007]最小矩形覆盖 凸包+旋转卡壳

    题目大意 用最小矩形覆盖平面上所有的点 分析 有一结论:最小矩形中有一条边在凸包的边上,不然可以旋转一个角度让面积变小 简略证明 我们逆时针枚举一条边 用旋转卡壳维护此时最左,最右,最上的点 注意 注 ...