文章目录
知识总览
android
主题换肤通常借助LayoutInflater#setFactory
实现换肤。
换肤步骤:
- 通过解析外部的
apk
压缩文件,创建自定义的Resource
对象去访问apk
压缩文件的资源。 - 借助
LayoutInfater#setFactoy
,将步骤(1)中的资源应用到View
的创建过程当中。
认识setFactory
平常设置或者获取一个View
时,用的较多的是setContentView
或LayoutInflater#inflate
,setContentView
内部也是通过调用LayoutInflater#inflate
实现(具体调用在AppCompatViewInflater#setContentView(ind resId)
中)。
通过LayoutInflater#inflate
可以将xml
布局文件解析为所需要的View
,通过分析LayoutInflate#inflate
源码,可以看到.xml
布局文件在解析的过程中会调用LayoutInflater#rInflate
,随后会通过调用LayoutInflater#createViewFromTag
来创建View
。这里推荐《遇见LayoutInflater&Factory》
下面一起看看View
的创建过程LayoutInflate#createViewFormTag
:
View createViewFromTag(View parent, String name, Context context, AttributeSet attrs,
boolean ignoreThemeAttr) {
if (name.equals("view")) {
name = attrs.getAttributeValue(null, "class");
}
// Apply a theme wrapper, if allowed and one is specified.
if (!ignoreThemeAttr) {
final TypedArray ta = context.obtainStyledAttributes(attrs, ATTRS_THEME);
final int themeResId = ta.getResourceId(0, 0);
if (themeResId != 0) {
context = new ContextThemeWrapper(context, themeResId);
}
ta.recycle();
}
if (name.equals(TAG_1995)) {
// Let's party like it's 1995!
return new BlinkLayout(context, attrs);
}
try {
View view;
if (mFactory2 != null) {
//根据attrs信息,通过mFactory2创建View
view = mFactory2.onCreateView(parent, name, context, attrs);
} else if (mFactory != null) {
//根据attrs信息,通过mFactory创建View
view = mFactory.onCreateView(name, context, attrs);
} else {
view = null;
}
if (view == null && mPrivateFactory != null) {
view = mPrivateFactory.onCreateView(parent, name, context, attrs