LayoutInflater
LayoutInfalter
,刚开始学习Android的时候可能纳闷这个究竟是个什么,布局增压泵?好奇怪的名字啊。或许我们可以从官方的文档中找到答案。接下来我也会主要通过对官方文档中的解释进行介绍。
Instantiates a layout XML file into its corresponding View objects. It is never used directly. Instead, use Activity.getLayoutInflater() or Context.getSystemService to retrieve a standard LayoutInflater instance that is already hooked up to the current context and correctly configured for the device you are running on.
To create a new LayoutInflater with an additional Factory for your own views, you can use cloneInContext(Context) to clone an existing ViewFactory, and then call setFactory(Factory) on it to include your Factory.
For performance reasons, view inflation relies heavily on pre-processing of XML files that is done at build time. Therefore, it is not currently possible to use LayoutInflater with an XmlPullParser over a plain XML file at runtime; it only works with an XmlPullParser returned from a compiled resource (R.something file.)
Note: This class is not thread-safe and a given instance should only be accessed by a single thread.
LayoutInflater是什么?
其实就介绍了LayoutInflater的作用,将XML文件实例化成对应的View对象。说的更直白一些,就是一个使用XML布局文件的手段。我们可以先将一个XML布局文件转换为对象,然后通过对这个对象的一些操作来完成对布局的操作。对此的话,我更愿意称LayoutInflater
为布局加载器
那么究竟该怎么使用呢?文档中明确的指出,我们从来都不直接去使用它,而是通过Activity.getLayoutInflater()或者Context.getSystemService的方式。对应的样例,如下所示:
// 在一个Activity中使用get方法:
LayoutInflater inflater = getLayoutInflater();
// 或者获取对应的服务
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
有的时候,也会遇到如下的方法进行获取:
LayoutInflater inflater = LayoutInflater.from(view.getContext());
为什么Android的官方介绍中没有提到这种方式呢?我觉可能是通过from()
方法获取的这种方式获取LayoutInflater
对象本质上还是和第二种方式是一样,可以看一下对应方法的源码就知道了:
public static LayoutInflater from(@UiContext Context context) {
LayoutInflater LayoutInflater =
(LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
if (LayoutInflater == null) {
throw new AssertionError("LayoutInflater not found.");
}
return LayoutInflater;
}
LayoutInflater.Factory
为什么在Android中又要多引入这个类呢?正如文档中所说的,其作用就是为了帮助我们定义的View的。
比如我们遇到如下的场景:
- 替换特定的View,比如将
TextView
替换成我们自定的View。 - 在View初始化的时候,增加额外的逻辑。比如初始化的时候设置默认的字体或样式。
- 对View的创建过程进行监控,以方便我们进行调试。
对此,我们都可以使用setFactory()的方式,设置一个我们自己编写的工厂来拦截对View的创建,并返回自定义的View。
貌似还是有点蒙蒙的,这到底是个啥,我们可以通过对其的使用来详细了解一下。其使用可以简单的分为两部分,一部分是创建我们自己的视图工厂,另一部分是按照文档的描述去创建新的LayoutInflater
。这里我们以将布局中所有TextView替换成Button的场景进行演示一下
- 首先是创建一个自己的视图工厂。逻辑很好理解,就是实现了Factory的接口,逻辑则是遇到名字为TextView的时候,返回Button对象。
public class CustomFactory implements LayoutInflater.Factory2 {
@Nullable
@Override
public View onCreateView(@Nullable View parent, @NonNull String name,