android插件式换肤,Android学习之插件化换肤

a7578cbfbaf9

做好计划,定期复盘,感知责任,提高执行力换肤有好几种方式,今天主要来看看插件化换肤的相关知识,本文主要涉及到的知识点:

setContentView实现源码分析、LayoutInflater中的inflate解析、

Observer与Observable、 Application的onCreate的妙用

1.setContentView实现源码分析

a7578cbfbaf9

setContentView源码分析流程.png上图为setContentView的一个调用流程,具体可以参考源码做详细分析

a7578cbfbaf9

布局层级结构.png2.LayoutInflater中的inflate解析

2.1 对于inflate其主要做以下说明:

public View inflate(XmlPullParser parser, @Nullable ViewGroup root, boolean attachToRoot) {

//此处代码省略

}

主要是一般在使用是会正常传入root参数,并且attachToRoot为false,如果attachToRoot为ture,有可能会出现设置layout_width参数生效问题(此部分可作为后面的一个补充点做说明)。

另外,会调用createViewFromTag对XML布局进行解析,下面会介绍个这个接口;

2.2 createViewFromTag解析:

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) {

view = mFactory2.onCreateView(parent, name, context, attrs);

} else if (mFactory != null) {

view = mFactory.onCreateView(name, context, attrs);

} else {

view = null;

}

if (view == null && mPrivateFactory != null) {

view = mPrivateFactory.onCreateView(parent, name, context, attrs);

}

if (view == null) {

final Object lastContext = mConstructorArgs[0];

mConstructorArgs[0] = context;

try {

if (-1 == name.indexOf('.')) {

view = onCreateView(parent, name, attrs);

} else {

view = createView(name, null, attrs);

}

} finally {

mConstructorArgs[0] = lastContext;

}

}

return view;

} catch (InflateException e) {

throw e;

} catch (ClassNotFoundException e) {

final InflateException ie = new InflateException(attrs.getPositionDescription()

+ ": Error inflating class " + name, e);

ie.setStackTrace(EMPTY_STACK_TRACE);

throw ie;

} catch (Exception e) {

final InflateException ie = new InflateException(attrs.getPositionDescription()

+ ": Error inflating class " + name, e);

ie.setStackTrace(EMPTY_STACK_TRACE);

throw ie;

}

}

从代码看首先会判断mFactory2 ,mFactory 来进行createView即创建view,这两个可谓是作用很大会用来做拦截view的创建过程,从而可以做本文将的重点换肤。心静1秒。。。

3. Observer与Observable

Observer作为被观察者,在换肤中可以用来检测每个Activity的换肤需求,而用来接管系统的View的生产过程的类(SkinLayoutInflaterFactory)即可作为观察者,当当前Activity需要换肤时,通过setChanged()和notifyObservers接口即可通知观察类通过update() 接口进行更新换肤;

4. Application的onCreate的妙用

Application的onCreate()方法调用是早于Anctivity的onCreate(),此点在换肤中的应用是Factory的设置,由自定义Factory来接管,以及会走后面的onCreatView进行新皮肤的加载;另外,比如Gride在第一次调用时会出现加载图片很慢的情况,因为在第一次是Gride会做一些初始化的动作,所以如果出现这种问题,可以考虑在Application的onCreate()中简单做一个Gride的一个初始化init,可以优化此问题。。。。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值