[TOC]
概述
大家对LayoutInflater一定不陌生,它主要用于加载布局,在Fragment的onCreateView方法、ListView Adapter的getView方法等许多地方都可以见到它的身影。今天主要聊聊LayoutInflater的用法以及加载布局的工作原理。
在 Android UI 开发中,经常需要用到 LayoutInflater 类,它的基本作用是将 xml 布局文件解析成 View / View 树。除了基本的布局解析功能,LayoutInflater 还可以用于实现 动态换肤、视图转换、属性转换 等需求。
LayoutInflater是什么?
LayoutInflater是一个用于将xml布局文件加载为View或者ViewGroup对象的工具,我们可以称之为布局加载器。
获取LayoutInflater
首先要注意LayoutInflater本身是一个抽象类,我们不可以直接通过new的方式去获得它的实例,通常有下面五种方式:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
| public static View inflate(Context context, @LayoutRes int resource, ViewGroup root) { LayoutInflater factory = LayoutInflater.from(context); return factory.inflate(resource, root); }
public LayoutInflater getLayoutInflater() { return getWindow().getLayoutInflater(); }
private LayoutInflater mLayoutInflater;
public PhoneWindow(Context context) { super(context); mLayoutInflater = LayoutInflater.from(context); }
public LayoutInflater getLayoutInflater() { return mLayoutInflater; }
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; }
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
|
从上面,我们可以看到,我们获取LayoutInflate归根结底最终都是调用getSystemService(…)的逻辑中。
所以,现在我们看getSystemService(…)内的逻辑:
1 2 3 4
| @Override public Object getSystemService(String name) { return SystemServiceRegistry.getSystemService(this, name); }
|
我们需要从SystemServiceRegistr中获取LAYOUT_INFLATER_SERVICE
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
|
private static final Map<String, ServiceFetcher<?>> SYSTEM_SERVICE_FETCHERS = new ArrayMap<String, ServiceFetcher<?>>();
static { ... 1. 注册 Context.LAYOUT_INFLATER_SERVICE 与服务获取器 关注点:CachedServiceFetcher 关注点:PhoneLayoutInflater registerService(Context.LAYOUT_INFLATER_SERVICE, LayoutInflater.class, new CachedServiceFetcher<LayoutInflater>() { @Override public LayoutInflater createService(ContextImpl ctx) { 注意:getOuterContext(),参数使用的是 ContextImpl 的代理对象,一般是 Activity return new PhoneLayoutInflater(ctx.getOuterContext()); }}); ... }
2. 根据 name 获取服务对象 public static Object getSystemService(ContextImpl ctx, String name) { ServiceFetcher<?> fetcher = SYSTEM_SERVICE_FETCHERS.get(name); return fetcher != null ? fetcher.getService(ctx) : null; }
注册服务与服务获取器 private static <T> void registerService(String serviceName, Class<T> serviceClass, ServiceFetcher<T> serviceFetcher) { SYSTEM_SERVICE_FETCHERS.put(serviceName, serviceFetcher); }
3. 服务获取器创建对象 static abstract interface ServiceFetcher<T> { T getService(ContextImpl ctx); }
|
1 2 3 4
| public View inflate(@LayoutRes int resource, @Nullable ViewGroup root) { return inflate(resource, root, root != null); }
|
rInflate方法
文章参考:https://www.jianshu.com/p/81a698aaf05c