最近在做Android项目,也没有时间从头开始系统学一遍,大部分知识点只能一边做项目一遍积累。 今天在做一个需求写布局的时候在
加藤
同学的建议下使用RecyclerView
来实现,在编码过程中接触到LayoutInflater
这玩意,也算是第一次接触吧,整理下相关知识点。
LayoutInflater
是一个用于将xml
布局文件加载为View
或者ViewGroup
对象的工具,我们可以称之为**布局加载器**。
将layout
的xml
布局文件实例化为View
类对象,LayoutInflater
的作用类似于 findViewById()
,不同点是LayoutInflater
是用来找layout
文件夹下的xml
布局文件,并且实例化!而 findViewById()
是找具体某一个xml
下的具体 widget
控件(如:Button
,TextView
等)。
LayoutInflater
本身是一个抽象类,不能直接通过new
的方式来获取它的实例。
上代码:
第一种方法
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
第二种方法
LayoutInflater inflater = LayoutInflater.from(context);
第三种方法
// 在Activity内部调用getLayoutInflater()方法
这三种方式本质是相同的,从源码中可以看出:
public static LayoutInflater from(Context context) {
LayoutInflater LayoutInflater =
(LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
if (LayoutInflater == null) {
throw new AssertionError("LayoutInflater not found.");
}
return LayoutInflater;
}
在Activity
内部调用getLayoutInflater
方法其实调用的是PhoneWindow
的mLayoutInflater
:
public PhoneWindow(Context context) {
super(context);
mLayoutInflater = LayoutInflater.from(context);
}
这几个方法实际上殊途同归,都是通过调用Context
的getSystemService
方法去获取。
获取到的是PhoneLayoutInflater
这个实现类。
public class Policy implements IPolicy {
...
public LayoutInflater makeNewLayoutInflater(Context context) {
return new PhoneLayoutInflater(context);
}
}
实例化LayoutInflater
之后,就要将layout
的xml
布局文件实例化为View
类对象。
View view=inflater.inflate(R.layout.ID, null);
点击进入sdk
源码,可以发现inflate
方法有以下几个重载方法:
它们返回的值都是View
对象。
其中 public View inflate (int resource, ViewGroup root)
最为常用。
示例代码:
LayoutInflater inflater = (LayoutInflater)getSystemService(LAYOUT_INFLATER_SERVICE);
View view = inflater.inflate(R.layout.custom, (ViewGroup)findViewById(R.id.test));
//EditText editText = (EditText)findViewById(R.id.content);// error
EditText editText = (EditText)view.findViewById(R.id.content);
指定了第二个参数 ViewGroup root
,当然也可以设置为 null
值。
root != null, attachToRoot == true
传进来的布局会被加载成为一个View并作为子View添加到root中,最终返回root;
而且这个布局根节点的android:layout_xxx参数会被解析用来设置View的大小;
root == null, attachToRoot无意义
当root为空时,attachToRoot无论是什么都没有意义。此时传进来的布局会被加载成为一个View并直接返回;
布局根View的android:layout_xxx
属性会被忽略,即android:layout_xx属性只有依附在某个ViewGroup中才能生效;
root != null, attachToRoot == false
传进来的布局会被加载成为一个View并直接返回。
布局根View的android:layout_xxx
属性会被解析成LayoutParams并设置在View上,此时root只用于设置布局根View的大小和位置。
从根节点开始,递归解析xml
的每个节点。
每一步递归的过程是:通过节点名称(全类名),使用ClassLoader
创建对应类的实例,也就是View
,然后,将这个View
添加到它的上层节点(父View
)。
同时会解析对应xml
节点的属性作为View
的属性。每个层级的节点都会被生成一个个的View
,并根据View
的层级关系add
到对应的直接父View
(上层节点)中,最终返回一个包含了所有解析好的子View
的布局根View
。
参考资料
分享计划
博客内容将同步至腾讯云+社区,邀请大家一同入驻:https://cloud.tencent.com/
许可协议
本文采用 署名-非商业性使用-相同方式共享 4.0 国际 许可协议,转载请注明出处。
扫码关注腾讯云开发者
领取腾讯云代金券
Copyright © 2013 - 2025 Tencent Cloud. All Rights Reserved. 腾讯云 版权所有
深圳市腾讯计算机系统有限公司 ICP备案/许可证号:粤B2-20090059 深公网安备号 44030502008569
腾讯云计算(北京)有限责任公司 京ICP证150476号 | 京ICP备11018762号 | 京公网安备号11010802020287
Copyright © 2013 - 2025 Tencent Cloud.
All Rights Reserved. 腾讯云 版权所有