android下apkplug通用主题(皮肤)切换解决方案之主应用-01
2014-05-22 14:16
507 查看
该文章是基于apkplug V1.6.8 进行说明的
我们提供了一个demo做为参考,项目下载地址为:http://git.oschina.net/plug/IMThemeDemo
该 IMThemeDemo 实现了简单的聊天泡泡切换功能,同时主题包(插件)是托管在apkplug的云服务器上的。所以要阅读项目的完整代码可以先看插件托管服务开发系列文章 <插件托管服务开发指南>
demo运行效果图:
一,apkplug的主题说明
apkplug主题解决方案摒弃了以往以图片替换的形式切换效果的方式,转而使用android原生资源和素材来切换UI样式和效果。所以从体验效果上是一次极大的提升。
二,apkplug主题(皮肤)切换适用范围
apkplug主题解决方案适用安卓界面的整个层次。其包括通用主题样式,和自定义控件样式切换两个层面
1.通用主题样式
与系统主题相似(Activity.setTheme()) 我们在系统与app(插件)之间可新增一层主题,三层主题已叠加的形式形成最终结果
2.自定义控件样式
大部分情况下我们的app都会自己设计主题,或者针对某写控件设计自己的样式,在这种模式下以上的通用主题便缺少
其存在的意义了。因此apkplug也提供一种简单有效的方案,允许开发者根据自己的需求定义自定义UI控件样式的替换规则
在不失通用性兼容性简洁性的情况下达到最好的体验。
三,主题(皮肤)切换流程
1.通用主题样式
通用主题样式有apkplug框架在底层适配,app开发过程中无需过多考虑,只要主题包设置了通用主题样式,app中的Activity 主题将自定替换(最前面的Activity需刷新后才能体现)
2.自定义控件样式
自定义控件样式的替换由于每个app的特殊性的原因,没法做统一的规范。但apkplug经过几个月的努力研发出一套简单有效的实施方案,允许开发者自由定制适合自己app的替换接口。而主题包设计者根据该接口简单配置即可。
四,自定义控件样式替换接口举例
1.定义替换接口
以 IMThemeDemo项目为例,我们需要替换聊天界面的聊天泡泡,所以自定义了以下的这样一个接口
com.apkplug.imthemedemo.themeinterface.chatstyles
以上接口返回值是一个资源ID,它可能是一张图片或者一个xml布局样式。但它将由主题包(插件)提供。
2.主程序监听主题切换事件
以上我们定义了一套UI样式的切换接口,但我们主应用并不知道合适会有主题包来替换我们现有的样式。所以我们需要一个监听器来监听这个接口事件,一下是模板代码 (此处设计一些OSGI服务方面的知识,不明白的同学可看 OSGI服务基本原理),但我们提供模板代码,开发者可以先实现在研究其原理。
定义一个专门监听接口事件变化的单例类
com.apkplug.imthemedemo.ThemeChengFactory
3.界面创建时判断是否切换样式
上一步我们已经实现了监听接口注册与注销事件,但我们还没有将切换的样式绑定到具体的控件上来。这一步我们将完成这一块工作
根据上一段代码我们得知 ThemeChengFactory类中的chatstyles service 成员变量在主题包注册以后不为空,没有注册时为空。这样我们便通过判断 serice是否为空来判断是否有主题样式可切换。同时我们判断返回值是否为-1来判断主题包提供的样式是否完整
注:我们约定主题包可能只提供了接口的部分控件样式,其他样式返回-1 表示没有提供相应资源
4.在创建控件时设置样式
1)聊天泡泡样式
com.apkplug.imthemedemo.adapter.ChatMsgViewAdapter
2)聊天界面背景图片样式
com.apkplug.imthemedemo.activity.ChatActivity
5.监听主题切换事件,重刷UI
第四步我们完成了在UI创建刷新时判断并替换新的样式,但目前为止我们还不只到什么时候应该刷新UI。以下将解决这个问题
当主题包设置了可替换主题以后,apkplug会给监听器发送主题切换事件,我们可注册这样一个监听器实时监听主题切换事件刷新activity从而实现实时换肤的功能。
com.apkplug.imthemedemo.activity.MainActivity
我们没有在ChatActivity界面设置监听器重刷的原因是,每次设置主题我们都会到主题包的Activity中,并且返回以后每次都重新进入ChatActivity界面,所以ChatActivity不需要重刷(因为它每次都是新的)
完成以上步骤以后主应用完成了,但这还不够因为我们还没有开发主题包(插件)呢。下一节将讲解怎么开发主题包,它同样简单快捷
我们提供了一个demo做为参考,项目下载地址为:http://git.oschina.net/plug/IMThemeDemo
该 IMThemeDemo 实现了简单的聊天泡泡切换功能,同时主题包(插件)是托管在apkplug的云服务器上的。所以要阅读项目的完整代码可以先看插件托管服务开发系列文章 <插件托管服务开发指南>
demo运行效果图:
一,apkplug的主题说明
apkplug主题解决方案摒弃了以往以图片替换的形式切换效果的方式,转而使用android原生资源和素材来切换UI样式和效果。所以从体验效果上是一次极大的提升。
二,apkplug主题(皮肤)切换适用范围
apkplug主题解决方案适用安卓界面的整个层次。其包括通用主题样式,和自定义控件样式切换两个层面
1.通用主题样式
与系统主题相似(Activity.setTheme()) 我们在系统与app(插件)之间可新增一层主题,三层主题已叠加的形式形成最终结果
2.自定义控件样式
大部分情况下我们的app都会自己设计主题,或者针对某写控件设计自己的样式,在这种模式下以上的通用主题便缺少
其存在的意义了。因此apkplug也提供一种简单有效的方案,允许开发者根据自己的需求定义自定义UI控件样式的替换规则
在不失通用性兼容性简洁性的情况下达到最好的体验。
三,主题(皮肤)切换流程
1.通用主题样式
通用主题样式有apkplug框架在底层适配,app开发过程中无需过多考虑,只要主题包设置了通用主题样式,app中的Activity 主题将自定替换(最前面的Activity需刷新后才能体现)
2.自定义控件样式
自定义控件样式的替换由于每个app的特殊性的原因,没法做统一的规范。但apkplug经过几个月的努力研发出一套简单有效的实施方案,允许开发者自由定制适合自己app的替换接口。而主题包设计者根据该接口简单配置即可。
四,自定义控件样式替换接口举例
1.定义替换接口
以 IMThemeDemo项目为例,我们需要替换聊天界面的聊天泡泡,所以自定义了以下的这样一个接口
com.apkplug.imthemedemo.themeinterface.chatstyles
01 | public interface chatstyles { |
02 | //我们协定如果 返回值小于0为未设置状态 |
03 | //主题样式版本,如果主题样式接口有所改变就利用这来判断 |
04 | public int Version(); |
05 | //聊天界面右侧Item 背景样式 |
06 | public int chat_right_msg_background(); |
07 | //聊天界面左侧Item 背景样式 |
08 | public int chat_left_msg_background(); |
09 | //聊天界面背景 |
10 | public int chatbackground(); |
11 | } |
2.主程序监听主题切换事件
以上我们定义了一套UI样式的切换接口,但我们主应用并不知道合适会有主题包来替换我们现有的样式。所以我们需要一个监听器来监听这个接口事件,一下是模板代码 (此处设计一些OSGI服务方面的知识,不明白的同学可看 OSGI服务基本原理),但我们提供模板代码,开发者可以先实现在研究其原理。
定义一个专门监听接口事件变化的单例类
com.apkplug.imthemedemo.ThemeChengFactory
01 | mcontext.addServiceListener( |
02 | new ServiceListener(){ |
03 | @Override |
04 | public void serviceChanged(ServiceEvent event) { |
05 | switch (event.getType()) { |
06 | case ServiceEvent.REGISTERED: |
07 | if (ref == null ) { |
08 | //当有主题包注册了该接口,意味着它为我们提供样式切换的具体资源了 |
09 | ref = event.getServiceReference(); |
10 | service = (chatstyles) mcontext.getService(ref); |
11 | } |
12 | break ; |
13 | case ServiceEvent.UNREGISTERING: |
14 | if (ref == event.getServiceReference()) { |
15 | //主题包注销了该接口,意味着它不再提供切换的具体资源了 |
16 | mcontext.ungetService(ref); |
17 | service = null ; |
18 | ref = null ; |
19 | } |
20 | break ; |
21 | } |
22 |
23 | } |
24 | },String.format( "(objectclass=%s)" ,chatstyles. class .getCanonicalName()) ); |
上一步我们已经实现了监听接口注册与注销事件,但我们还没有将切换的样式绑定到具体的控件上来。这一步我们将完成这一块工作
根据上一段代码我们得知 ThemeChengFactory类中的chatstyles service 成员变量在主题包注册以后不为空,没有注册时为空。这样我们便通过判断 serice是否为空来判断是否有主题样式可切换。同时我们判断返回值是否为-1来判断主题包提供的样式是否完整
注:我们约定主题包可能只提供了接口的部分控件样式,其他样式返回-1 表示没有提供相应资源
4.在创建控件时设置样式
1)聊天泡泡样式
com.apkplug.imthemedemo.adapter.ChatMsgViewAdapter
01 | chatstyles cs=ThemeChengFactory.getInstance( null ).getService(); |
02 | if (cs!= null ){ |
03 | //chatstyles 不为空表示有主题包提供替换的资源 |
04 | ViewHolder v= (ViewHolder)convertView.getTag(); |
05 | if (isComMsg){ |
06 | if (cs.chat_left_msg_background()!=- 1 ){ |
07 | //主题包提供的该控件资源ID |
08 | v.tvContent.setBackgroundResource(cs.chat_left_msg_background()); |
09 | } |
10 | } else { |
11 | if (cs.chat_right_msg_background()!=- 1 ){ |
12 | //主题包提供的该控件资源ID |
13 | v.tvContent.setBackgroundResource(cs.chat_right_msg_background()); |
14 | } |
15 | } |
16 | } |
com.apkplug.imthemedemo.activity.ChatActivity
1 | chatstyles cs=ThemeChengFactory.getInstance( null ).getService(); |
2 | if (cs!= null ){ |
3 | //有主题包提供接口样式 |
4 | if (cs.chatbackground()!=- 1 ){ |
5 | //提供该控件样式资源ID |
6 | mListView.setBackgroundResource(cs.chatbackground()); |
7 | } |
8 | } |
第四步我们完成了在UI创建刷新时判断并替换新的样式,但目前为止我们还不只到什么时候应该刷新UI。以下将解决这个问题
当主题包设置了可替换主题以后,apkplug会给监听器发送主题切换事件,我们可注册这样一个监听器实时监听主题切换事件刷新activity从而实现实时换肤的功能。
com.apkplug.imthemedemo.activity.MainActivity
01 | public void ListenerTheme(){ |
02 | BundleContext context=frame.getSystemBundleContext(); |
03 | ServiceReference reference=context.getServiceReference(RegThemeChengeListener. class .getName()); |
04 | if ( null !=reference){ |
05 | //查询主题切换事件监听器注册服务 |
06 | final RegThemeChengeListener service=(RegThemeChengeListener) context.getService(reference); |
07 | if (service!= null ){ |
08 | //找到服务注册一个监听器,实时监听主题切换动态 |
09 | service.registerOnThemeListener( |
10 | new OnThemeChengeListener(){ |
11 | @SuppressLint ( "NewApi" ) |
12 | @Override |
13 | public void afterChenged(org.osgi.framework.Bundle arg0, int arg1) { |
14 | //主题切换以后我们重刷Activity |
15 | MainActivity. this .recreate(); |
16 | System.out.println( "afterChenged" ); |
17 | //把上一个监听器注销,因为界面被重刷以后我们又注册了一个新的监听器 |
18 | service.unregisterOnThemeListener( this ); |
19 | } |
20 | @Override |
21 | public void beforeChenge( |
22 | org.osgi.framework.Bundle bb, int arg1,org.osgi.framework.Bundle tob, int arg2) { |
23 |
24 | } |
25 | }); |
26 | } |
27 | context.ungetService(reference); |
28 | } |
29 | } |
完成以上步骤以后主应用完成了,但这还不够因为我们还没有开发主题包(插件)呢。下一节将讲解怎么开发主题包,它同样简单快捷
相关文章推荐
- android下apkplug通用主题(皮肤)切换解决方案之主题包开发-02
- apkplug主题皮肤切换之通用主题-04
- Android 应用制定主题,QQ皮肤APK原理
- apkplug主题皮肤切换之自定义样式-05
- Android中实现应用切换主题机制
- 下载android应用的apk文件变成了zip解决方案
- apkplug主题切换之申请apkplug.pem证书-06
- android第三方应用apk安装和运行控制解决方案
- Android中实现应用切换主题机制
- Android中实现应用切换主题机制
- Android应用切换皮肤功能实现(二)
- android第三方应用apk安装和运行控制解决方案
- android插件化-apkplug框架基本结构-01
- 下载android应用的apk文件变成了zip解决方案
- android进行主题切换不重启整个应用(style方式)
- #爱加密杯#Android应用切换皮肤功能实现
- 主题:Android 皮肤apk实现换肤
- android 应用动态切换主题
- Android 应用主题切换
- Android应用切换皮肤功能实现