LinearLayout具体解释三:LayoutInflater创建View过程分析
上次讲到以下这么一段代码,这段代码的作用就是解析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过程分析的更多相关文章
- Js基础知识4-函数的三种创建、四种调用(及关于new function()的解释)
在js中,函数本身属于对象的一种,因此可以定义.赋值,作为对象的属性或者成为其他函数的参数.函数名只是函数这个对象类的引用. 函数定义 // 函数的三种创建方法(定义方式) function one( ...
- 2019年6月14日 Web框架之Django_07 进阶操作(MTV与MVC、多对多表三种创建方式、前后端传输数据编码格式contentType、ajax、自定义分页器)
摘要 MTV与MVC 多对多表三种创建方式 ajax ,前后端传输数据编码格式contentType 批量插入数据和自定义分页器 一.MVC与MTV MVC(Model View Controller ...
- Android使用默认样式创建View的几个姿势
以下内容是分析安卓源码所得: 1: 使用默认样式创建View的方式, 源码文件 Button.Java 注:此文参考http://www.linzenews.com/ 中的内容所写,如侵删! 2: ...
- 使用Java代码来创建view
使用Java代码来创建view 一.简介 需要了解的知识 二.方法 1)java代码创建view方法 * 1.先建view对象 View view= View.inflate(this, R.layo ...
- Django-多对多关系的三种创建方式-forms组件使用-cookie与session-08
目录 表模型类多对多关系的三种创建方式 django forms 组件 登录功能手写推理过程 整段代码可以放过来 forms 组件使用 forms 后端定义规则并校验结果 forms 前端渲染标签组件 ...
- geotrellis使用(三)geotrellis数据处理过程分析
之前简单介绍了geotrellis的工作过程以及一个简单的demo,最近在此demo的基础上实现了SRTM DEM数据的实时分析以及高程实时处理,下面我就以我实现的上述功能为例,简单介绍一下geotr ...
- Fixflow引擎解析(三)(模型) - 创建EMF模型来读写XML文件
Fixflow引擎解析(四)(模型) - 通过EMF扩展BPMN2.0元素 Fixflow引擎解析(三)(模型) - 创建EMF模型来读写XML文件 Fixflow引擎解析(二)(模型) - BPMN ...
- VMware vSphere 服务器虚拟化之二十二桌面虚拟化之创建View Composer链接克隆的虚拟桌面池
VMware vSphere 服务器虚拟化之二十二桌面虚拟化之创建View Composer链接克隆的虚拟桌面池 在上一节我们创建了完整克隆的自动专有桌面池,在创建过程比较缓慢,这次我们将学习创建Vi ...
- IOS程序创建view
在IOS程序中创建view有六种方式 首先创建一个GLViewController类,继承UIViewController. 然后进入GLAppDelegate.m,在- (BOOL)applicat ...
随机推荐
- Selenium WebDriver-打开3个网址截图,文件夹用年月日命名,图片用当前时分秒命名
import os import os.path import time from selenium import webdriver urls=["http://www.baidu.com ...
- Python学习-day6 面向对象概念
开始学习面向对象,可以说之前的学习和编程思路都是面向过程的,从上到下,一步一步走完. 如果说一个简单的需求,用面向过程实现起来相对容易,但是如果在日常生产,面向对象就可以发挥出他的优势了. 程序的可扩 ...
- python学习--Django mvc框架简介
让我们一览 Django 全貌 urls.py 网址入口,关联到对应的views.py中的一个函数(或者generic类),访问网址就对应一个函数. views.py 处理用户发出的请求,从urls. ...
- 如何用jquery+json来写页面
以下是json数据表: [ { "p" : "银川市", "c" : [{"c1":"兴庆区"},{ ...
- 聊聊、Java Keytool P12 转 JKS
最近公司合作机构需要更改服务证书,总共给了 3 个文件过来.openapi-cert.p12.openapi-cert.key.openapi-cert.crt. openapi-cert.crt - ...
- 聊聊、Nginx 初始化错误信息
这篇文章我们继续学习 main 方法,我们先来看看 ngx_debug_init() 这个方法. 从方法名我们也知道,debug初始化.我们先看看方法位置在哪.我们来断点在这个方法上面. Functi ...
- POJ 1240 Pre-Post-erous!
k叉树的前序和后续遍历,问一共有多少种这样的k叉树 这个就是树的同构,组合数就能解决 同样的题目在51nod也有的,我的另一篇博客 POJ 1240 Pre-Post-erous! We are al ...
- 【bzoj2521】[Shoi2010]最小生成树 网络流最小割
题目描述 Secsa最近对最小生成树问题特别感兴趣.他已经知道如果要去求出一个n个点.m条边的无向图的最小生成树有一个Krustal算法和另一个Prim的算法.另外,他还知道,某一个图可能有多种不同的 ...
- 【bzoj1604】[Usaco2008 Open]Cow Neighborhoods 奶牛的邻居 旋转坐标系+并查集+Treap/STL-set
题目描述 了解奶牛们的人都知道,奶牛喜欢成群结队.观察约翰的N(1≤N≤100000)只奶牛,你会发现她们已经结成了几个“群”.每只奶牛在吃草的时候有一个独一无二的位置坐标Xi,Yi(l≤Xi,Yi≤ ...
- POJ——3070Fibonacci(矩阵快速幂)
Fibonacci Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 12329 Accepted: 8748 Descri ...