Android 打造自己的个性化应用(二):应用程序内置资源实现换肤功能
通过应用程序内置资源实现换肤,典型的应用为QQ空间中换肤的实现. 应用场景为: 应用一般不大,且页面较少,风格相对简单,一般只用实现部分资源或者只用实现背景的更换.
此种换肤方式实现的思路:
1. 把几套皮肤放在res/drawable目录里,然后用SharedPreferences来记录当前皮肤的资源id.然后在程序启动时加载Activity背景。
2. 主要的实现在皮肤管理器SkinManager类中. 将皮肤资源的ID加入集合中. 由该类同一调度皮肤更换,如初始化皮肤,获取当前皮肤符号以及具体的对应资源的更换皮肤.
接下来看一下效果图:


内置皮肤的实现相对比较简单,下面直接上代码:
AndroidMainfest.xml
- <?xml version="1.0" encoding="utf-8"?>
- <manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="com.tony.skindemo"
- android:versionCode="1"
- android:versionName="1.0" >
- <uses-sdk android:minSdkVersion="8" />
- <application
- android:icon="@drawable/ic_launcher"
- android:label="@string/app_name" >
- <activity
- android:label="@string/app_name"
- android:name="com.tony.skindemo.SkinDemoActivity" >
- <intent-filter >
- <action android:name="android.intent.action.MAIN" />
- <category android:name="android.intent.category.LAUNCHER" />
- </intent-filter>
- </activity>
- </application>
- </manifest>
布局文件:
main.xml
- <?xml version="1.0" encoding="utf-8"?>
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent"
- android:orientation="vertical" >
- <TextView
- android:textColor="#ff00ff"
- android:text="程序皮肤更换"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content" />
- <RadioGroup
- android:id="@+id/skin_options"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- >
- <RadioButton
- android:layout_weight="1"
- android:id="@+id/radioButton1"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="风格1" />
- <RadioButton
- android:layout_weight="1"
- android:id="@+id/radioButton2"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="风格2" />
- <RadioButton
- android:layout_weight="1"
- android:id="@+id/radioButton3"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="风格3" />
- <RadioButton
- android:layout_weight="1"
- android:id="@+id/radioButton4"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="风格4" />
- <RadioButton
- android:layout_weight="1"
- android:id="@+id/radioButton5"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="风格5" />
- </RadioGroup>
- </LinearLayout>
程序主Activity
- package com.tony.skindemo;
- import android.app.Activity;
- import android.os.Bundle;
- import android.view.MotionEvent;
- import android.view.Window;
- import android.view.WindowManager;
- import android.widget.RadioButton;
- import android.widget.RadioGroup;
- import android.widget.RadioGroup.OnCheckedChangeListener;
- public class SkinDemoActivity extends Activity {
- private SkinSettingManager mSettingManager;
- private RadioButton radioButton1;
- private RadioButton radioButton2;
- private RadioButton radioButton3;
- private RadioButton radioButton4;
- private RadioButton radioButton5;
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- // 取消标题栏
- requestWindowFeature(Window.FEATURE_NO_TITLE);
- // 完成窗体的全屏显示 // 取消掉状态栏
- getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
- WindowManager.LayoutParams.FLAG_FULLSCREEN);
- setContentView(R.layout.main);
- // 初始化皮肤
- mSettingManager = new SkinSettingManager(this);
- mSettingManager.initSkins();
- //通过单选按钮设置皮肤(可自定义更换的方式,如导航栏,也可以加上预览功能,此处不再实现)
- radioButton1 = (RadioButton) findViewById(R.id.radioButton1);
- radioButton2 = (RadioButton) findViewById(R.id.radioButton2);
- radioButton3 = (RadioButton) findViewById(R.id.radioButton3);
- radioButton4 = (RadioButton) findViewById(R.id.radioButton4);
- radioButton5 = (RadioButton) findViewById(R.id.radioButton5);
- RadioGroup radioGroup = (RadioGroup) findViewById(R.id.skin_options);
- radioGroup.setOnCheckedChangeListener(new OnCheckedChangeListener() {
- @Override
- public void onCheckedChanged(RadioGroup group, int checkedId) {
- switch (checkedId) {
- case R.id.radioButton1:
- mSettingManager.changeSkin(1);
- break;
- case R.id.radioButton2:
- mSettingManager.changeSkin(2);
- break;
- case R.id.radioButton3:
- mSettingManager.changeSkin(3);
- break;
- case R.id.radioButton4:
- mSettingManager.changeSkin(4);
- break;
- case R.id.radioButton5:
- mSettingManager.changeSkin(5);
- break;
- default:
- break;
- }
- }
- });
- }
- // 这里为了简单实现,实现换肤
- public boolean onTouchEvent(MotionEvent event) {
- mSettingManager.toggleSkins();
- return super.onTouchEvent(event);
- }
- }
- <pre name="code" class="java"></pre><pre></pre><p></p><pre></pre>皮肤管理器:<p></p><p></p><pre name="code" class="java">package com.tony.skindemo;
- import android.app.Activity;
- import android.content.SharedPreferences;
- /**
- * 皮肤管理器
- * @author tony
- *
- */
- public class SkinSettingManager {
- public final static String SKIN_PREF = "skinSetting";
- public SharedPreferences skinSettingPreference;
- private int[] skinResources = { R.drawable.default_wallpaper,
- R.drawable.wallpaper_c,R.drawable.wallpaper_d,R.drawable.wallpaper_f,
- R.drawable.wallpaper_g
- };
- private Activity mActivity;
- public SkinSettingManager(Activity activity) {
- this.mActivity = activity;
- skinSettingPreference = mActivity.getSharedPreferences(SKIN_PREF, 3);
- }
- /**
- * 获取当前程序的皮肤序号
- *
- * @return
- */
- public int getSkinType() {
- String key = "skin_type";
- return skinSettingPreference.getInt(key, 0);
- }
- /**
- * 把皮肤序号写到全局设置里去
- *
- * @param j
- */
- public void setSkinType(int j) {
- SharedPreferences.Editor editor = skinSettingPreference.edit();
- String key = "skin_type";
- editor.putInt(key, j);
- editor.commit();
- }
- /**
- * 获取当前皮肤的背景图资源id
- *
- * @return
- */
- public int getCurrentSkinRes() {
- int skinLen = skinResources.length;
- int getSkinLen = getSkinType();
- if(getSkinLen >= skinLen){
- getSkinLen = 0;
- }
- return skinResources[getSkinLen];
- }
- public void toggleSkins(){
- int skinType = getSkinType();
- if(skinType == skinResources.length - 1){
- skinType = 0;
- }else{
- skinType ++;
- }
- setSkinType(skinType);
- mActivity.getWindow().setBackgroundDrawable(null);
- try {
- mActivity.getWindow().setBackgroundDrawableResource(getCurrentSkinRes());
- } catch (Throwable e) {
- e.printStackTrace();
- }
- }
- /**
- * 用于初始化皮肤
- */
- public void initSkins(){
- mActivity.getWindow().setBackgroundDrawableResource(getCurrentSkinRes());
- }
- /**
- * 随即切换一个背景皮肤
- */
- public void changeSkin(int id) {
- setSkinType(id);
- mActivity.getWindow().setBackgroundDrawable(null);
- try {
- mActivity.getWindow().setBackgroundDrawableResource(getCurrentSkinRes());
- } catch (Throwable e) {
- e.printStackTrace();
- }
- }
- }
- </pre><br><p></p><p>就这样,通过程序内置皮肤的基本功能完成了.</p><p>若想在自己的应用中实现,仍需注意以下几点(实现起来并不复杂,此处不再写具体实现):<br></p><p>1. 实现多个activity的更换皮肤. 需要利用自定义MyApplication类,继承自Application. 并加入activity的集合属性.用于存储应用所有的activity<br></p><p> 修改SkinManager,在更换皮肤时,从application中取出该集合,进行遍历并更换皮肤</p><p><br></p><p>2. 可以优化用户体验,通过导航栏方式进入更换皮肤界面,并可以加入预览功能,当确定修改配置后,才完成更换皮肤功能.</p><p>3. 加入style.theme等资源,实现更加复杂的皮肤更换. 具体实现同更换背景.<br></p><p><br></p><p><br></p><p><br></p><p><br></p>
Android 打造自己的个性化应用(二):应用程序内置资源实现换肤功能的更多相关文章
- 一种简单的实现:Android一键换肤功能
现在的APP开发,通常会提供APP的换肤功能,网上流传的换肤代码和实现手段过于复杂,我把原作者的代码重新整理抽取出来,转换成Eclipse项目,重新整理成正确.可直接运行的项目. 代码运行结果如图. ...
- Android一键换肤功能:一种简单的实现
Android一键换肤功能:一种简单的实现 现在的APP开发,通常会提供APP的换肤功能,网上流传的换肤代码和实现手段过于复杂,这里有一个开源实现,我找了一大堆,发现这个项目相对较为简洁:htt ...
- Android 打造自己的个性化应用(一):应用程序换肤主流方式的分析与概述
Android平台api没有特意为换肤提供一套简便的机制,这可能是外国的软件更注重功能和易用,不流行换肤.系统不提供直接支持,只能自行研究. 换肤,可以认为是动态替换资源(文字.颜色.字体大小.图片. ...
- Android 换肤功能的实现(Apk插件方式)
一.概述 由于Android 没有提供一套统一的换肤机制,我猜可能是因为国外更注重功能和体验的原因 所以国内如果要做一个漂亮的换肤方案,需要自己去实现. 目前换肤的方法大概有三种方案: (1)把皮肤资 ...
- Unit05: JavaScript对象概述 、 常用内置对象一 、 常用内置对象二 、 常用内置对象三
Unit05: JavaScript对象概述 . 常用内置对象一 . 常用内置对象二 . 常用内置对象三 常用内置对象使用演示: <!DOCTYPE html> <html> ...
- Flex AIR应用换肤功能(Android和IOS)
说明 换肤功能,即将整个应用的皮肤都进行更换,其实质,是动态加载swf文件的过程,而这些swf文件则有css文件编译而来. 关于换肤功能,在android和ios系统的实现方式是不同的.主要原因,是因 ...
- Android QMUI实战:实现APP换肤功能,并自动适配手机深色模式
Android换肤功能已不是什么新鲜事了,市面上有很多第三方的换肤库和实现方案. 之所以选择腾讯的QMUI库来演示APP的换肤功能,主要原因: 1.换肤功能的实现过程较简单.容易理解: 2.能轻松适配 ...
- Android 打造自己的个性化应用(四):仿墨迹天气实现-->自定义扩展名的zip格式的皮肤
在这里谈一下墨迹天气的换肤实现方式,不过首先声明我只是通过反编译以及参考了一些网上其他资料的方式推测出的换肤原理, 在这里只供参考. 若大家有更好的方式, 欢迎交流. 墨迹天气下载的皮肤就是一个zip ...
- Android 打造自己的个性化应用(三):应用程序的插件化
在android的项目开发中,都会遇到后期功能拓展增强与主程序代码变更的现实矛盾,也就是程序的灵活度. 由于linux平台的安全机制,再加上dalvik的特殊机制,各种权限壁垒,使得开发一个灵活多变的 ...
随机推荐
- Hacker(23)----破解常见文件密码
Win7中,office文档.压缩文件等都是常见的文件,这些文档含有重要的信息,即使用户为这些文件设置了密码,黑客也会有办法破解. 一.破解office文档密码 破解office文档密码常用工具是Ad ...
- ASE中的主要数据库
Adaptive Server包括多种类型数据库: 必需数据库. “附加功能”数据库 .例子数据库 .应用数据库 1.必需数据库 master 数据库包含系统表,这些系统表中存储的数据被用来管理,有 ...
- .NET基础拾遗(4)委托为何而生?
生活中的例子: 你早上要吃包子作为早饭,那么你可能让你爸爸或者妈妈帮你做,那你就会调用 爸爸.要包子() 或妈妈.要包子() 返回包子对象. 但是如果你爸妈不在家的时候,你只能去街上买,问题是你根本不 ...
- 动态绑定GridView数据源遇到问题
1.GridView中的Button控件响应Command事件的时候出现System.ArgumentException: 回发或回调参数无效, 设置<pages enableEventVali ...
- untiy绘制网格mesh
关于绘制网格, 雨松前辈 已经解释的非常的到位,这里我只是搬运工,实在是感觉自己去描述的话不会有雨松大神描述的清楚,该文章循序渐进,一步步引导读者去理解unirty 绘图机制,真的是没有比这个再好得了 ...
- 转载Eclipse中Maven WEB工程tomcat项目添加调试
转载地址: http://blog.csdn.net/free4294/article/details/38260581 一.建立一个maven WEB项目 1.file->new->o ...
- Gora官方文档之二:Gora对Map-Reduce的支持
参考官方文档:http://gora.apache.org/current/tutorial.html 项目代码见:https://code.csdn.net/jediael_lu/mygoradem ...
- Kendo Web UI Grid里时间格式转换
我和大家分享一下我的kendo的学习心得.如果不好的地方多多包含或者给我留言请看图 kendo里时间格式如图Oder Date列里的格式.但是我们想把时间转换成中国人习惯的格式.如Shipped Da ...
- 继刚接触play framework后,一些心得
我是个小菜鸟,我这些体会跟心得纯属个人观点,仅供参考,勿喷,我想记录下学习的历程,不断成长 在play2.0的框架里面 用到的最多的语言就是scala,对于习惯了java语言的我们来说 看这些语言 ...
- 文成小盆友python-num2 数据类型、列表、字典
一.先聊下python的运行过程 计算机是不能够识别高级语言的,所以当我们运行一个高级语言程序的时候,就需要一个“翻译机”来从事把高级语言转变成计算机能读懂的机器语言的过程.这个过程分成两类,第一种是 ...