Android的xml布局文件是不能直接显示在手机界面上的,手机界面上能够显示的只有视图(View),若要使xml布局文件显示在手机页面上就必须将xml文件转化为视图,进行xml解析,下面是几种转化方法。
//1.通过Activity中的getLayoutInflater()方法
View view = getLayoutInflater().inflate(resource, root, attachToRoot);
//2.通过系统服务获取布局加载器
LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View view = inflater.inflate(resource, root, attachToRoot);
//3.通过View的静态inflate()方法
View view = View.inflate(resource, root, attachToRoot);
//4.通过LayoutInflater的inflate()方法
View view = LayoutInflater.from(context).inflate(resource, root, attachToRoot);
1 Activity中的的getLayoutInflater()
我们先来分析Activity的getLayoutInflater()
@NonNull
public LayoutInflater getLayoutInflater() {
//这里直接去看phoneWindow中的getLayoutInflater();
return getWindow().getLayoutInflater();
}
//我们可以看到,这里在phoneWindow的构造方法中就有LayoutInflater.form(context).
public PhoneWindow(Context context) {
super(context);
mLayoutInflater = LayoutInflater.from(context);
}
1 | 而我们知道在Activity中,phonewindow的初始化 |
2.通过系统服务获取加载器getSystemService()
@Override
public Object getSystemService(@ServiceName @NonNull String name) {
if (WINDOW_SERVICE.equals(name)) {
return mWindowManager;
} else if (SEARCH_SERVICE.equals(name)) {
ensureSearchManager();
return mSearchManager;
}
//这里因为传入的string是"layout_inflater",所以会直接调用super方法。
//也就是直接到ContextThemeWrapper方法中的getSystemService
return super.getSystemService(name);
}
@Override
public Object getSystemService(String name) {
//String是相等的
if (LAYOUT_INFLATER_SERVICE.equals(name)) {
if (mInflater == null) {
//内部还是调用的layoutInflater.from方法,直接clone了一个context而已。
mInflater = LayoutInflater.from(getBaseContext()).cloneInContext(this);
}
return mInflater;
}
return getBaseContext().getSystemService(name);
}
1 | 总结:getSystemService的内部还是在调用LayoutInflater.from() |
3 通过View的静态inflate()方法
public static View inflate(Context context, @LayoutRes int resource, ViewGroup root) {
//依旧是通过layoutInflater.from()
LayoutInflater factory = LayoutInflater.from(context);
//这里的inflate实际上就是进行xml解析
return factory.inflate(resource, root);
}
1 | 总结:通过View的静态inflate()的内部在调用LayoutInflater.from() |
4. 通过LayoutInflater的inflate()方法
我们既然知道 四种方法,内部 实际上都是在调用LayoutInflater.from(context),那么这里就需要着重对这段源码来进行分析。
/**
* Obtains the LayoutInflater from the given context.
*/
public static LayoutInflater from(Context context) {
LayoutInflater LayoutInflater =
//这里就很奇怪,内部是getSystemService,又回到了系统服务获取加载器。
(LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
if (LayoutInflater == null) {
throw new AssertionError("LayoutInflater not found.");
}
return LayoutInflater;
而inflate 则实际上就是xml解析的过程。
我们是否对这种方式感到诧异?
getlayoutinflater()最终调用的是layoutinflater.from,里面又调用的getSystemService,而getSystemService内部则又是调用了
LayoutInflater.from(getBaseContext());
其实这个LayoutInflater就涉及到单例模式