LayoutInflater 加载布局文件源码

LayoutInflater是一个用于将xml布局文件加载为View或者ViewGroup对象的工具,我们可以称之为布局加载器。

获取LayoutInflater实例

有3种方式获取到取LayoutInflater实例

第一种

(LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
复制代码

第二种 是针对第一种的封装

LayoutInflater.from(context); 复制代码

第三种 在Activity中,封装了获取LayoutInflater的接口

Activity.getLayoutInflater()
复制代码

LayoutInflater 的使用创建View

创建View,有4个重载方式

  • inflate(int resource, ViewGroup root)
  • inflate(int resource, ViewGroup root, boolean attachToRoot)
  • inflate(XmlPullParser parser, ViewGroup root)
  • inflate(XmlPullParser parser, ViewGroup root, boolean attachToRoot)

一般常用的是前2种

方式 结果
inflate( resourceId, rootView) 将解析布局文件生成的View,添加到rootView中
addView(parseView, layoutParams)
inflate( resourceId, null) 创建不带LayoutParams的View
布局文件里顶层空间的LayoutParams将会失效
inflate( resourceId, null, false) 同上
inflate( resourceId, rootView, false) 创建带LayoutParams的View
布局文件里顶层空间的LayoutParams有效果
但是不会加入到rootView中
inflate( resourceId, rootView, true) 同第一个

源码解析

LayoutInflate
|
|-inflate(XmlPullParser parser, @Nullable ViewGroup root, boolean attachToRoot)||-final View temp = createViewFromTag(root, name, inflaterContext, attrs); 创建根节点View||-if(root != nul) root.generateLayoutParams(attrs);|根据根节点属性创建,根节点View的LayoutParams||-if(!attachToRoot) temp.setLayoutParams(params); |如果添加到rootView,设置布局文件根View的LayoutParams属性||- rInflateChildren(parser, temp, attrs, true);|加载布局文件中子View||-if (root != null && attachToRoot) root.addView(temp, params);|将布局文件中根节点View添加到rootView中这里解释了,inflate重载方法中root和attachToRoot这两个参数的含义LayoutInflate
|
|-View createViewFromTag(View parent, String name, Context context, AttributeSet attrs,boolean ignoreThemeAttr)
|根据布局文件节点名称创建View|||-if (mFactory2 != null) view = mFactory2.onCreateView(parent, name, context, attrs);|1.优先mFactory2创建view||-if (mFactory != null)  view = mFactory.onCreateView(name, context, attrs);|2.mFactory创建view||-if (view == null && mPrivateFactory != null)  view = mPrivateFactory.onCreateView(parent, name, context, attrs);|3.mPrivateFactory创建view||-view = createView(name, null, attrs);|4.直接通过反射方式创建View||-clazz = mContext.getClassLoader().loadClass(prefix != null ? (prefix + name) : name).asSubclass(View.class);|-constructor = clazz.getConstructor(mConstructorSignature);|-final View view = constructor.newInstance(args);|通过反射创建View如果继承自AppCompateActivity,mFactory2!=null,创建AppCompateTextView,等对象LayoutInflate
|
|-rInflateChildren(parser, temp, attrs, true);
|加载子View||-final View view = createViewFromTag(parent, name, context, attrs);|创建子View||-final ViewGroup.LayoutParams params = viewGroup.generateLayoutParams(attrs);|生成子View LayoutParmas属性||-rInflateChildren(parser, view, attrs, true);|创建该节点下子View||-viewGroup.addView(view, params);|将子View添加到父View中||-if (finishInflate) parent.onFinishInflate();|结束递归rInflateChildrenrInflateChildren函数是一个根据布局文件的节点递归遍历生生成子View,并添加到View树中,
当某个节点下面的所有子节点View解析生成完成后,才会调起onFinishInflate回调复制代码

利用LayoutInflate替换布局文件中默认View

  1. 实现LayoutInflater.Factory2接口
public class TestLayoutFactory implements LayoutInflater.Factory2 {private static final String TAG = "TestLayoutFactory";private final AppCompatDelegate delegate;public TestLayoutFactory(AppCompatDelegate delegate) {this.delegate = delegate;}@Overridepublic View onCreateView(View parent, String name, Context context, AttributeSet attrs) {if (TextUtils.equals("TextView", name)) {return new CustomTextView(context, attrs);}return delegate.createView(parent, name, context, attrs);}@Overridepublic View onCreateView(String name, Context context, AttributeSet attrs) {return null;}
}
复制代码
  1. 在AppCompatActivity的onCreate()方法中设置LayoutInfalte.Factory
    override fun onCreate(savedInstanceState: Bundle?) {LayoutInflaterCompat.setFactory2(layoutInflater, TestLayoutFactory(getDelegate()))super.onCreate(savedInstanceState)setContentView(R.layout.activity_test_layout_factory)}
复制代码

一定要在super.onCreate(savedInstanceState) 代码之前设置,否则会报错:

Caused by: java.lang.IllegalStateException: A factory has already been set on this LayoutInflater
复制代码

因为在调用父类的onCreate()方法中,已经创建了LayoutInfalte.Factory,再次创建的时候,就会报错了

转载于:https://juejin.im/post/5b8666fb518825430e57226e

2.2 LayoutInflater 加载布局文件源码相关推荐

  1. Android--使用LayoutInflater加载布局文件的三种方法

    LayoutInflater的作用类似于 findViewById(), 不同点是LayoutInflater是用来找layout文件夹下的xml布局文件,并且实例化! 而 findViewById( ...

  2. HTML卡片式布局源码,html5自适应卡片式设计动态加载整站源码_

    html5自适应卡片式设计动态加载整站源码 该模板是非常容易存活的,这样的程序很容易吸引访客点击,提升ip流量和pv是非常有利的,随意挂点联盟广告都能养活程序. 本套整站源码采使用现在非常流行的全屏自 ...

  3. 2款不同样式的CSS3 Loading加载动画 附源码

    原文:2款不同样式的CSS3 Loading加载动画 附源码 我们经常看到的Loading加载很多都是转圈圈的那种,今天我们来换一种有创意的CSS3 Loading加载动画,一种是声波形状的动画,另一 ...

  4. html动画爱心制作代码,CSS心形加载的动画源码的实现

    废话不多说上代码,代码很简答,研究一下就明白了,有不明白的可以问我. .heart-loading { margin-top: 120px; width: 200px; height: 200px; ...

  5. 【Android 热修复】热修复原理 ( 合并两个 Element[] dexElements | 自定义 Application 加载 Dex 设置 | 源码资源 )

    文章目录 一.合并两个 Element[] dexElements 二. 完整修复包加载工具类 三. 源码资源 一.合并两个 Element[] dexElements 在 [Android 热修复] ...

  6. 这篇文章绝对让你深刻理解java类的加载以及ClassLoader源码分析

    前言 package com.jvm.classloader;class Father2{public static String strFather="HelloJVM_Father&qu ...

  7. Android使用addView动态加载布局文件

    第一步,要获取要将动态加载内容置入的容器 relativeLayout RelativeLayout relativeLayout = (RelativeLayout) findViewById(R. ...

  8. spring bean加载过程_Spring源码剖析3:Spring IOC容器的加载过程

    本文转自五月的仓颉 https://www.cnblogs.com/xrq730 本系列文章将整理到我在GitHub上的<Java面试指南>仓库,更多精彩内容请到我的仓库里查看 https ...

  9. 美团、点评、猫眼App下拉加载效果的源码分享

    今天我准备拿大众点评.美团.猫眼电影三款App的实例来分享一下APICloud下拉加载这个模块的效果. 美团App下拉加载效果 以美团中的下拉酷似动画的萌萌着小人儿效果作为参考,来实现的一个加载模块. ...

最新文章

  1. Python中的super()用法
  2. java 不可修改的集合对象_java集合:关于hashmap存储一个对象,中间改变对象的值,为什么再remove不能用新名字来删除...
  3. 【dp】POJ-2209
  4. Leet Code OJ 202. Happy Number [Difficulty: Easy]
  5. 学网络编程很好的参考源码
  6. CMU 15-213 Introduction to Computer Systems学习笔记(2) Bits,Bytes,Integer
  7. Matlab用巴特沃斯带通滤波器产生窄带高斯噪声并进行时域频域分析
  8. 何为监督学习、无监督学习、强化学习、弱监督学习、半监督学习、多示例学习?
  9. 80坐标系(3度带)转经纬度
  10. 分享5款干净好用的电脑浏览器,用最后一款工作不累
  11. 保存下载图片(taro h5)
  12. 模拟器安装app 报错误 INSTALL_FAILED_NO_MATCHING_ABIS
  13. python csv文件和xlsx文件混杂时,提取指定列数据并合并
  14. php爬取房源,Python 爬虫 链家二手房(自行输入城市爬取)
  15. 【discuzx2】forum_index.php文件的分析
  16. 思想,坚持,信仰,一切
  17. Unity模型动画骨骼错位解决办法
  18. 计算机应用素描色彩,美术统考素描、色彩、速写考场技巧全攻略
  19. ZOJ 3587 Marlon's String 扩展KMP
  20. 淘宝天猫API_获取商品详情原数据

热门文章

  1. 剑指offer (03):数组中重复的数字 (C++ Python 实现)
  2. Fedora升级后Python虚拟环境中的pip报错
  3. android studio service directory path,Android Studio User目录缓存搬移到指定目录
  4. 5.10 Ext JS Grid中 WidgetColumn(组件列)的使用
  5. JavaScript 字符串截取方法汇总
  6. Tex, LaTex概念及实例
  7. android 按钮点击返回顶部,微信浏览器点击系统返回,安卓返回会重载页面回到页面顶部,iOS则返回则会保留之前浏览位置的解决方法...
  8. 12306一直提示网络有问题_教你怎么在12306官网订购火车票 火车票查询12306订购...
  9. MATLAB基本信号的产生
  10. php怎么获取cid,Typecho根据文章cid获取文章信息