android换肤
来源:互联网 发布:epub转azw3软件 编辑:程序博客网 时间:2024/05/22 13:14
方式一、
国内有很多的软件都支持皮肤定制,这也是与国外软件重大不同之一,国外用户注重社交、邮件等功能,国内用户则重视音乐、小说、皮肤等功能,本节课程就来讲解Android应用程序如何实现换肤功能。
软件换肤从功能上可以划分三种:
1) 软件内置多个皮肤,不可由用户增加或修改;
最低的自由度,软件实现相对于后两种最容易。
2) 官方提供皮肤供下载,用户可以使用下载的皮肤;
用户可选择下载自己喜欢的皮肤,有些玩家会破解皮肤的定制方法,自己做皮肤使用,或者传到网上给大家用。
3) 官方提供皮肤制作工具或方法,用户可自制皮肤。
这种方式使用户有参与感,自由度较高。用户可根据自己的喜好定制软件的皮肤。有些软件官网提供皮肤定制的工具或者方法,我建议最好有可视化带向导的工具。用户只要自己找一些图片、修改文字的字体替换就可以了。用户可以上传自制的皮肤,提供其他用户下载,还可以赚得一些虚拟货币或者奖品什么的。这种一般都是打包为.zip格式的。扩展名可由各公司自定义,有制作工具的话直接导出来最方便。
首先我们要弄清楚换肤的定义,软件皮肤包括图标、字体、布局、交互风格等,换肤就是换掉皮肤包括的部分或所有资源。
前面提到的三种皮肤,从软件实现上来看,它们的本质区别是皮肤是否内置到应用程序中。对于内置的实现比较简单,只要在开发应用的过程中设计几套皮肤供用户选择。这里用到的知识不超过Android基础,不详细讲解。
本节课程重点讲解如何实现皮肤与应用程序分离。
皮肤一般含有多个文件,例如图片、配置等文件,分散的文件不利于传输和使用,最好打包。打包的格式一般选择zip格式。这里分两种情况,一种是apk,例如AdwLauncher,它的桌面皮肤格式是一个apk;另一种是自定义扩展名,例如墨迹天气皮肤扩展名是mja,搜狗输入法的皮肤扩展名是sga,它们的文件格式实际上都是zip。
下面我们分别讲解。
一.apk格式
现在的问题变成了一个应用如何读取另一个apk中的资源。
在android系统中,apk之间可以相互读取数据的条件是:有同样的签名,并且AndroidManifest.xml文件中配置的android:sharedUserId属性值相同,那么两个apk运行在同一个进程中,可以互相访问任意数据。
方法如下:
1) 应用程序和皮肤程序的AndroidManifest.xml中配置
例如: android:sharedUserId="com.kris.skin" ,值可以是做任意的,
2) 文件与应用apk中对同一功能的皮肤文件名要一致
例如:应用程序的背景图片路径:\SkinDemo\res\drawable-hdpi\bg.png
那么皮肤apk中的背景图片文件路径也应该是:
CustomSkin\res\drawable-hdpi\bg.png
3)访问资源的方法 获取到org.yuchen.customskin对应的Context,通过返回的context对象就可以访问到org.yuchen.customskin中的任何资源。
例如:应用apk要获得皮肤apk中的bg.png, 这样就得到了图片的引用,其他xml资源文件的获取方式也是类似的。
二.自定义扩展名的zip格式的皮肤
技术点在于如何去读取zip文件中的资源以及皮肤文件存放策略。
方案:如果软件每次启动都去读取SD卡上的皮肤文件,速度会比较慢。较好的做法是提供一个皮肤设置的界面,用户选择了哪一个皮肤,就把那个皮肤文件解压缩到”/data/data/[package name]/skin”路径下,这样不需要跨存储器读取,速度较快,而且不需要每次都去zip压缩包中读取,不依赖SD卡中的文件,即使皮肤压缩包文件被删除了也没有关系。
实现方法:
1. 在软件的帮助或者官网的帮助中提示用户将皮肤文件拷贝到SD卡指定路径下。
2. 在软件中提供皮肤设置界面。可以在菜单或者在设置中。可参考墨迹、搜狗输入法、QQ等支持换肤的软件。
3. 加载指定路径下的皮肤文件,读取其中的缩略图,在皮肤设置界面中显示,将用户选中的皮肤文件解压缩到”/data/data/[package name]/skin”路径下。
4. 软件中优先读取”/data/data/[package name]/skin/”路径下的资源。如果没有则使用apk中的资源。
下面是我做的实例的截图与source ,我只测试了一下通过apk 来换肤的功能 ,到少其它的方法就留给大家去实验吧,不过记得实验了也上传图来大家一起分享哟。
图来了:
换肤前的截图:
换肤后的截图:
工程源码来了,re_skin是主程序 ,re_skin1是皮质程序,也就是提供资源的:
source.zip
方式二、
界面上有说明,得先导入 皮肤文件,再换肤哦。。。
下面是皮肤文件,也就是一个包括资源文件的zip包,在这里去解压 zip包用到了这个帖子中的方法:
《[Android实例] 利用antzip包来进行解压与压缩》
http://www.eoeandroid.com/thread-102534-1-1.html
在运行项目前,记得先要下面的skin包上传到自己的sdcard目录下哦。当然这个名字啊,路径啊,你也可以自己在代码里面去改,甚至于zip包里面的资源也可以自己的修改,这就留给大家去发挥了。为了读取的快速及安全性,也可以把解压的目录放到程序有私有目录下面去哈,在这里为了方便就没去做这一步了,皮肤包来了:
skin.zip
下面是代码来啰 !!
Re_Skin2.zip
方式三、
通过Style来完成
作者:kris更新于 04月07日访问(3014)评论(66)
在long long ago ,写过两篇文章来实现换肤,在论坛里面不敢说人人皆知,但是人气还是到位了的.如果你还不知道,那赶快再去看看吧:
[Android实例] 【Kris专题】android 换肤 http://www.eoeandroid.com/thread-102060-1-1.html
[Android实例] 【kris专题】android 换肤(续) http://www.eoeandroid.com/thread-102536-1-1.html
另外一些在本文中会使用到的些知识:
【Kris专题】android Style 小结 http://www.eoeandroid.com/thread-99671-1-1.html
[Android实例] 【Kris专题】android:shape的使用 http://www.eoeandroid.com/thread-105450-1-1.html
1 2 3 4 5 6 7 8 91011121314151617
然后今天我将给大家带来更神奇也更方便的一种方法来完成换肤.至于大家在项目中使用哪种方法就看大家的实际的项目需求了.这种换肤的主要思路是通过 Style来完成,如果大家对 Style的应用还不是很清楚,或者说是甚至没听说过,那你就危险了,至少足以证明你在Android界里面有多菜了.如果应用不是很熟悉,或者说他的原理不是很清楚的,自己可以多查阅一些资料,在这里就不作更仔细的介绍了.我们还是通过Demo 来一步步守成整个换肤的过程吧..1.当然是建议一个Android projects. 项目名什么的就随便你自己取了.我推荐大家在写自己的一些 demo的时候,指导编译 sdk可以设置到最高,别老是在2.x 徘徊了,有意思吗?2.项目建议好之后,就准备好各种我们图片资源文件吧(你可以ps一些背景图,也可以通过style中的shape来制作一些资源.或者说在color.xml中定义好一些颜色值,当然最方便的还是下载我的demo啦,里面啥都有了,呵呵 )3.在res/values目录下建议一个attrs.xml.里面用来定义一些style 的属性.如下:```java<?xml version="1.0" encoding="utf-8"?><resources> <attr name="button" format="reference"/> <attr name="background" format="reference"/> <attr name="textColor" format="reference"/></resources>
1 2 3 4 5 6 7 8 91011121314151617181920212223
代码解释: 在上面的代码中,我们定义了三个属性(button,backgroud,textColor),这三个属性呢会在Style中用到,并且指出它的格式是引用形的. 比如说 button,它的值到时候我们会在style里面去设置,并且指向具体的某个资源文件. 4.然后到我们的res/values/style.xml了.(非常关键哦) ```java <resources xmlns:android="http://schemas.android.com/apk/res/android"> <style name="AppTheme_Default" parent="@android:style/Theme.Holo.Light.DarkActionBar"> <item name="button">@drawable/btn_grey</item> <item name="background">@drawable/backgroud2</item> <item name="textColor">@color/red</item> </style> <style name="AppTheme_Another" parent="AppTheme_Default"> <item name="button">@drawable/btn_blue</item> <item name="background">@drawable/backgroud1</item> <item name="android:actionBarStyle">@style/ActionBarStyle</item> </style> <style name="ActionBarStyle" parent="@android:style/Widget.Holo.Light.ActionBar.Solid.Inverse"> <item name="android:background">#33b5e5</item> </style> </resources>
1 2 3 4 5 6 7 8 9101112131415161718192021222324252627282930313233343536373839
代码解释: 在这里我们定义了三个style (AppTheme_Default,AppTheme_Another,ActionBarStyle),其中AppTheme_Default,AppTheme_Another表示我们的两套主题.ActionBarStyle为我们actionBar的样式. AppTheme_Default为默认的主题,它是继承至@android:style/Theme.Holo.Light.DarkActionBar.当然你也可以继承Android中任意的已经有的主题 或者是style , 你也可以选择不继承任何已经有的样式 . AppTheme_Another为我们第二套主题 ,它是继承至AppTheme_Default的.在这里我们可以覆写部分AppTheme_Default里面的值,也可以覆写全部AppTheme_Default里面的值,这个看你具体的主题,也可以扩展其它一些新的值. 比如说在AppTheme_Another中,没有覆写textColor的值 ,也就是在这两种主题中,我的文字的颜色值都是使用AppTheme_Default主题 中的值,都为红色.但是又新增了一个android:actionBarStyle的样式来改变actionBar 的样式.5.接下来呢,我们再实现一个基础类,BaseActivity来代替所有的activity完成主题的切换(当然要求程序里面所有的activity 都得继承至 BaseActivity).```javapublic class BaseActivity extends Activity { public int mTheme = R.style.AppTheme_Default; @Override protected void onCreate(Bundle savedInstanceState) { if (savedInstanceState == null) { mTheme = PreferenceHelper.getTheme(this); } else { mTheme = savedInstanceState.getInt("theme"); } setTheme(mTheme); super.onCreate(savedInstanceState); } @Override protected void onResume() { super.onResume(); if (mTheme != PreferenceHelper.getTheme(this)) { reload(); } } protected void reload() { Intent intent = getIntent(); overridePendingTransition(0, 0); intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION); finish(); overridePendingTransition(0, 0); startActivity(intent); }}
1 2 3 4 5 6 7 8 91011
代码解释: onCreate中,我们从preference中去获取到主题,并且设置给 activity. 在onresume中再去检查主题 是否已经改变? 如果已经改变了,就重新加载activity ,否则没有动作. reload就是finish当前 activity ,再启动当前activity啦. 6.万事俱备了,现在的问题是我们在atrrs中定义的button , background怎么使用呢? a).java代码:```java int[] attrs = new int[]{R.attr.button}; TypedArray typedArray = context.obtainStyledAttributes(attrs);
1 2 3 4 5 6 7 8 91011121314151617181920212223242526
具体的使用大家自行去测试了 b).直接在layout文件里面使用.比如我们 demo中的两个布局文件 .在这里我们例出一个来讲解. second.xml ```java <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:background="?attr/background" > <TextView android:id="@+id/textview" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textColor="?attr/textColor" android:layout_alignParentTop="true" android:layout_centerHorizontal="true" android:text="@string/msg_second" /> <Button android:id="@+id/button" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerInParent="true" android:background="?attr/button" android:text="@string/btn_text" /> </RelativeLayout>
1 2 3 4 5 6 7 8 91011
代码解释: android:background="?attr/background"在这里使用了我们在attrs.xml中的background属性. android:textColor="?attr/textColor" 使用了我们在attrs.xml中定义的textColor android:background="?attr/button" 在这里使用了我们在attrs.xml中定义的button属性 我们再来走一个这个调用的流程. 在生成布局文件中RelativeLayout的时候,系统找到attrs.xml中定义的backround,然后再去当前设置的theme(我们假设是AppTheme_Default)中找到background指向的资源@drawable/backgroud2然后加载到内存赋值给RelativeLayout的android:background.如果当前主题 是AppTheme_Another,就会导入@drawable/backgroud1给RelativeLayout的android:background 好的.基本就讲到这里了.大家可以多看看 demo .多自己摸过下. 具体的 Demo下载地址: [http://www.eoeandroid.com/thread-264902-1-1.html](http://www.eoeandroid.com/thread-264902-1-1.html)或者我的博客: [http://www.krislq.com/2013/04/android_class_change_skin/](http://www.krislq.com/2013/04/android_class_change_skin/)
声明:eoe文章著作权属于作者,受法律保护,转载时请务必以超链接形式附带如下信息
原文作者: kris
原文地址: http://my.eoe.cn/kris/archive/2245.html
- Android应用换肤
- android 换肤
- android 换肤
- Android换肤apk
- android 换肤 .
- Android应用换肤
- android换肤
- android换肤
- android换肤机制
- Android应用换肤
- android换肤实现
- Android换肤技术
- Android换肤Demo
- Android换肤系列
- Android换肤
- Android换肤框架
- android动态换肤
- Android 换肤小结
- Median of Two Sorted Arrays
- Android上dip、dp、px、sp等单位说明
- 异步FIFO 忙闲标志
- OOM讲课内容:图片缓存
- Matrix使用简介
- android换肤
- 使用hadoop和hive来进行应用的日志数据分析
- 移动互联网产品设计的五个核心要素
- Linux中报找不到xxx.so时的解决办法
- JavaScript+技巧与高级特性
- noBackend:前端优先的开发模式
- oracle数据字典及视图
- PDF添加书签
- 中国移动开发者社区 的账号和地址