更换皮肤(主题)的方式有很多种,首先要弄清楚换肤的定义,软件皮肤包括图标、字体、布局、交互风格等,换肤就是换掉皮肤包括的部分或者全部资源。皮肤一般含多个文件,有图片、配置等文件,分散的文件不利于传输和使用,所以最好打包。
从功能上讲,有只更换activity背景图片而不更换当前activity中控件的样式(图片来源于程序资源文件、sdCard、网络下载),也有更换只更换activity中控件样式而不更换activity背景的(控件样式包括文字颜色,控件背景如按钮、文本框等,图片圆角等随背景变化)等等。
从形式上来讲,有在当前主工程中提供不同主题样式资源名称(使用时只去选择对应的资源名称即可),也有在主题包中提供与主工程相同资源名字(apk形式、自定义压缩包形式)。或更换当前页面也可更换整个工程的全部页面。
用apk的方式或者自定义压缩包方式更换程序皮肤,不仅能更换activity、控件等背景,还能更换文字样式,按钮样式等一切在资源文件中定义了的主题样式,这样的方式,方便,简单,而且使主程序的apk包较小。
总之:
1) 应用内置多个皮肤供用户选择,不可由用户增加或修改,实现容易(在工程中定义多个样式即可);
2) 官方提供皮肤下载,用户下载安装使用(apk、自定义压缩包);
如果是apk皮肤包,那么先下载皮肤apk包,安装,然后使现在的程序读取新安装的apk包中的资源文件,下次再打开程序时,依旧读取的是上次设置的apk的资源,若主题apk被卸载,读取的则是默认的资源。
现在的问题就是应用软件如何读取皮肤包中的资源。
在android系统中,apk之间可以相互读取数据的条件是有相同的签名,并且在AndroidManifest.xml文件中配置的android:sharedUserId(android:sharedUserId参考http://blog.youkuaiyun.com/cigogo/article/details/7483676和http://blog.youkuaiyun.com/hmg25/article/details/6447067)的属性值相同,那么两个apk运行在同一个进程中,可以互相访问数据。
方法如下:
1) 应用程序和皮肤程序的AndroidManifest.xml中配置,例如:android:sharedUserId=”com.theme.skin”,值可以是任意的。
2) 应用程序文件与皮肤程序文件中,对同一功能的皮肤文件名要一致,例如:应用程序的背景图片路径:ThemeSkin\res\drawable-hdpi\bg.9.png,那么皮肤apk文件中的背景图片文件路径也应该是SkinRed\res\drawable-hdpi\bg.9.png
3) 访问资源文件的方法(完整代码见项目压缩包):
主程序:
获取已经安装了的皮肤包的包名、应用图标和应用名称,当然最重要的实包名,这样可以通过包名,去读取当前皮肤包中的其它资源的资源名称,从而去加载。
核心代码如下:
// 获取到