主题 : 换肤框架.

转载:

ximsfei的博客地址:
http://blog.csdn.net/ximsfei

1

背景

换肤方案原理在网上已经很多了, 这里不再详细描述, 强迫症的我总是想让提供给别人使用的SDK尽量好用, 哪怕是给自己带来额外的工作量, 经过一段时间的奋斗, 实现了一个自我感觉良好的换肤框架.

这里主要来看看Android 源码中”com.android.support:appcompat-v7”包的实现, 以及源码思想在Android-skin-support中的应用 – 如何打造一款好用的换肤框架.

2

appcompat-v7包实现

首先来看一下源码的实现:

AppCompatActivity源码

AppCompatActivity 将大部分生命周期委托给了AppCompatDelegate。
看下AppCompateDelegate的子类AppCompatDelegateImplV9实现:

从这可以看出通过实现LayoutInflaterFactory接口来实现换肤至少可以支持到api 9以上。

网上很多换肤框架的实现, 通过LayoutInflater.setFactory的方式, 在回调的onCreateView中解析每一个View的attrs, 判断是否有已标记需要换肤的属性, 比方说background, textColor, 或者说相应资源是否为skin_开头等等.
然后保存到map中, 对每一个View做for循环去遍历所有的attr, 想要对更多的属性进行换肤, 需要Activity实现接口, 将需要换肤的View, 以及相应的属性收集到一起。
那么是不是能够寻求一种让使用者更方便的方式来实现, 做一个侵入性尽量小的框架呢?

本着开发者应有的好奇心, 深入的研究了一些v7包的实现:
AppCompatDelegateImplV9中, 在LayoutInflaterFactory的接口方法
onCreateView 中将View的创建交给了AppCompatViewInflater

再来看一下AppCompatViewInflater中createView的实现

再看一下其中一个类AppCompatTextView的实现

AppCompatBackgroundHelper.Java

到这里我仿佛是发现了新大陆一样兴奋, 源码中可以通过拦截View创建过程, 替换一些基础的组件, 然后对一些特殊的属性(eg: background, textColor) 做处理, 那我们为什么不能将这种思想拿到换肤框架中来使用呢?

3

Android-skin-support换肤框架实现

抱着试一试不会少块肉的心情, 开始了我的换肤框架开发之路。

先简单讲一下原理:

  1. 参照源码实现在Activity onCreate中为LayoutInflater setFactory, 将View的创建过程交给自定义的SkinCompatViewInflater类来实现
  2. 重写系统组件, 实现换肤接口, 表明该控件支持换肤, 并在View创建之后统一收集
  3. 在重写的View中解析出需要换肤的属性, 并保存ResId到成员变量
  4. 重写类似setBackgroundResource方法, 解析需要换肤的属性, 并保存变量
  5. applySkin 在切换皮肤的时候, 从皮肤资源中获取资源

下面说一个简单的例子(SkinCompatTextView):

  1. 实现SkinCompatSupportable接口 2. 在构造方法中通过SkinCompatBackgroundHelper和SkinCompatTextHelper分别解析出background, textColor并保存 3. 重写setBackgroundResource和setTextAppearance, 解析出对应的资源Id, 表明该控件支持从代码中设置资源, 且支持该资源换肤 4. 在用户点击切换皮肤时调用applySkin方法设置皮肤

对于其他View也一样,复写其换肤相关的API,统一对外入口为applySkin。

SkinCompatTextHelper的部分实现:

4

开发过程中遇到的一些问题

在5.0以上, 使用color为ImageView设置src, 可以通过getColorStateList获取资源, 而在5.0以下, 需要通过ColorDrawable setColor的方式实现

还有很多问题, 有兴趣的同学可以来一起交流解决.

5

总结

这样的做法与网上其他框架相比优势在哪里, 为什么重复造轮子?

在增加框架开发成本的基础上降低了框架使用的成本, 我觉得更有意义, 一次开发, 所有Android 开发者都受用;

换肤框架对业务代码的侵入性比较小, 业务代码只需要继承自SkinCompatActivity, 不需要实现接口重写方法, 不需要其他额外的代码, 接入方便, 假如将来不想再使用本框架, 只需要把SkinCompatActivity改为原生Activity即可;

深入源码, 和源码实现方式类似, 兼容性更好.

为什么选择继承自AppCompatActivity, AppCompatTextView…而不是选择直接继承自Activity, TextView…

本身appcompat-v7包是一个support包, 兼容原生控件, 同时符合Material design, 我们只需要获取我们想要换肤的属性就可以在不破坏support包属性的前提下进行换肤;

参与开发的同学更多的话, 完全可以支持一套继承自Activity, TextView…的skin support包.

自定义View能否支持, 第三方控件是否支持换肤

答案是肯定的, 完全可以参照SkinCompatTextView的实现, 自己去实现自定义控件, 对于使用者来说, 扩展性很好.

开源地址:
https://github.com/ximsfei/Android-skin-support

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 162,158评论 4 370
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 68,600评论 1 307
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 111,785评论 0 254
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,655评论 0 220
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 53,075评论 3 295
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 41,002评论 1 225
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 32,146评论 2 318
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,918评论 0 211
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,671评论 1 250
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,838评论 2 254
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,318评论 1 265
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,636评论 3 263
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,343评论 3 244
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,187评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,982评论 0 201
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 36,126评论 2 285
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,934评论 2 279

推荐阅读更多精彩内容