通过应用程序内置资源实现换肤,典型的应用为QQ空间中换肤的实现. 应用场景为: 应用一般不大,且页面较少,风格相对简单,一般只用实现部分资源或者只用实现背景的更换.

此种换肤方式实现的思路:

1. 把几套皮肤放在res/drawable目录里,然后用SharedPreferences来记录当前皮肤的资源id.然后在程序启动时加载Activity背景。

2. 主要的实现在皮肤管理器SkinManager类中. 将皮肤资源的ID加入集合中. 由该类同一调度皮肤更换,如初始化皮肤,获取当前皮肤符号以及具体的对应资源的更换皮肤.

接下来看一下效果图:

内置皮肤的实现相对比较简单,下面直接上代码:

AndroidMainfest.xml

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <manifest xmlns:android="http://schemas.android.com/apk/res/android"
  3. package="com.tony.skindemo"
  4. android:versionCode="1"
  5. android:versionName="1.0" >
  6. <uses-sdk android:minSdkVersion="8" />
  7. <application
  8. android:icon="@drawable/ic_launcher"
  9. android:label="@string/app_name" >
  10. <activity
  11. android:label="@string/app_name"
  12. android:name="com.tony.skindemo.SkinDemoActivity" >
  13. <intent-filter >
  14. <action android:name="android.intent.action.MAIN" />
  15. <category android:name="android.intent.category.LAUNCHER" />
  16. </intent-filter>
  17. </activity>
  18. </application>
  19. </manifest>

布局文件:

main.xml

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3. android:layout_width="fill_parent"
  4. android:layout_height="fill_parent"
  5. android:orientation="vertical" >
  6. <TextView
  7. android:textColor="#ff00ff"
  8. android:text="程序皮肤更换"
  9. android:layout_width="fill_parent"
  10. android:layout_height="wrap_content" />
  11. <RadioGroup
  12. android:id="@+id/skin_options"
  13. android:layout_width="fill_parent"
  14. android:layout_height="wrap_content"
  15. >
  16. <RadioButton
  17. android:layout_weight="1"
  18. android:id="@+id/radioButton1"
  19. android:layout_width="wrap_content"
  20. android:layout_height="wrap_content"
  21. android:text="风格1" />
  22. <RadioButton
  23. android:layout_weight="1"
  24. android:id="@+id/radioButton2"
  25. android:layout_width="wrap_content"
  26. android:layout_height="wrap_content"
  27. android:text="风格2" />
  28. <RadioButton
  29. android:layout_weight="1"
  30. android:id="@+id/radioButton3"
  31. android:layout_width="wrap_content"
  32. android:layout_height="wrap_content"
  33. android:text="风格3" />
  34. <RadioButton
  35. android:layout_weight="1"
  36. android:id="@+id/radioButton4"
  37. android:layout_width="wrap_content"
  38. android:layout_height="wrap_content"
  39. android:text="风格4" />
  40. <RadioButton
  41. android:layout_weight="1"
  42. android:id="@+id/radioButton5"
  43. android:layout_width="wrap_content"
  44. android:layout_height="wrap_content"
  45. android:text="风格5" />
  46. </RadioGroup>
  47. </LinearLayout>

程序主Activity

  1. package com.tony.skindemo;
  2. import android.app.Activity;
  3. import android.os.Bundle;
  4. import android.view.MotionEvent;
  5. import android.view.Window;
  6. import android.view.WindowManager;
  7. import android.widget.RadioButton;
  8. import android.widget.RadioGroup;
  9. import android.widget.RadioGroup.OnCheckedChangeListener;
  10. public class SkinDemoActivity extends Activity {
  11. private SkinSettingManager mSettingManager;
  12. private RadioButton radioButton1;
  13. private RadioButton radioButton2;
  14. private RadioButton radioButton3;
  15. private RadioButton radioButton4;
  16. private RadioButton radioButton5;
  17. @Override
  18. public void onCreate(Bundle savedInstanceState) {
  19. super.onCreate(savedInstanceState);
  20. // 取消标题栏
  21. requestWindowFeature(Window.FEATURE_NO_TITLE);
  22. // 完成窗体的全屏显示 // 取消掉状态栏
  23. getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
  24. WindowManager.LayoutParams.FLAG_FULLSCREEN);
  25. setContentView(R.layout.main);
  26. // 初始化皮肤
  27. mSettingManager = new SkinSettingManager(this);
  28. mSettingManager.initSkins();
  29. //通过单选按钮设置皮肤(可自定义更换的方式,如导航栏,也可以加上预览功能,此处不再实现)
  30. radioButton1 = (RadioButton) findViewById(R.id.radioButton1);
  31. radioButton2 = (RadioButton) findViewById(R.id.radioButton2);
  32. radioButton3 = (RadioButton) findViewById(R.id.radioButton3);
  33. radioButton4 = (RadioButton) findViewById(R.id.radioButton4);
  34. radioButton5 = (RadioButton) findViewById(R.id.radioButton5);
  35. RadioGroup radioGroup = (RadioGroup) findViewById(R.id.skin_options);
  36. radioGroup.setOnCheckedChangeListener(new OnCheckedChangeListener() {
  37. @Override
  38. public void onCheckedChanged(RadioGroup group, int checkedId) {
  39. switch (checkedId) {
  40. case R.id.radioButton1:
  41. mSettingManager.changeSkin(1);
  42. break;
  43. case R.id.radioButton2:
  44. mSettingManager.changeSkin(2);
  45. break;
  46. case R.id.radioButton3:
  47. mSettingManager.changeSkin(3);
  48. break;
  49. case R.id.radioButton4:
  50. mSettingManager.changeSkin(4);
  51. break;
  52. case R.id.radioButton5:
  53. mSettingManager.changeSkin(5);
  54. break;
  55. default:
  56. break;
  57. }
  58. }
  59. });
  60. }
  61. // 这里为了简单实现,实现换肤
  62. public boolean onTouchEvent(MotionEvent event) {
  63. mSettingManager.toggleSkins();
  64. return super.onTouchEvent(event);
  65. }
  66. }
    1. <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;
    2. import android.app.Activity;
    3. import android.content.SharedPreferences;
    4. /**
    5. * 皮肤管理器
    6. * @author tony
    7. *
    8. */
    9. public class SkinSettingManager {
    10. public final static String SKIN_PREF = "skinSetting";
    11. public SharedPreferences skinSettingPreference;
    12. private int[] skinResources = { R.drawable.default_wallpaper,
    13. R.drawable.wallpaper_c,R.drawable.wallpaper_d,R.drawable.wallpaper_f,
    14. R.drawable.wallpaper_g
    15. };
    16. private Activity mActivity;
    17. public SkinSettingManager(Activity activity) {
    18. this.mActivity = activity;
    19. skinSettingPreference = mActivity.getSharedPreferences(SKIN_PREF, 3);
    20. }
    21. /**
    22. * 获取当前程序的皮肤序号
    23. *
    24. * @return
    25. */
    26. public int getSkinType() {
    27. String key = "skin_type";
    28. return skinSettingPreference.getInt(key, 0);
    29. }
    30. /**
    31. * 把皮肤序号写到全局设置里去
    32. *
    33. * @param j
    34. */
    35. public void setSkinType(int j) {
    36. SharedPreferences.Editor editor = skinSettingPreference.edit();
    37. String key  = "skin_type";
    38. editor.putInt(key, j);
    39. editor.commit();
    40. }
    41. /**
    42. * 获取当前皮肤的背景图资源id
    43. *
    44. * @return
    45. */
    46. public int getCurrentSkinRes() {
    47. int skinLen = skinResources.length;
    48. int getSkinLen = getSkinType();
    49. if(getSkinLen >= skinLen){
    50. getSkinLen = 0;
    51. }
    52. return skinResources[getSkinLen];
    53. }
    54. public void toggleSkins(){
    55. int skinType = getSkinType();
    56. if(skinType == skinResources.length - 1){
    57. skinType = 0;
    58. }else{
    59. skinType ++;
    60. }
    61. setSkinType(skinType);
    62. mActivity.getWindow().setBackgroundDrawable(null);
    63. try {
    64. mActivity.getWindow().setBackgroundDrawableResource(getCurrentSkinRes());
    65. } catch (Throwable e) {
    66. e.printStackTrace();
    67. }
    68. }
    69. /**
    70. * 用于初始化皮肤
    71. */
    72. public void initSkins(){
    73. mActivity.getWindow().setBackgroundDrawableResource(getCurrentSkinRes());
    74. }
    75. /**
    76. * 随即切换一个背景皮肤
    77. */
    78. public void changeSkin(int id) {
    79. setSkinType(id);
    80. mActivity.getWindow().setBackgroundDrawable(null);
    81. try {
    82. mActivity.getWindow().setBackgroundDrawableResource(getCurrentSkinRes());
    83. } catch (Throwable e) {
    84. e.printStackTrace();
    85. }
    86. }
    87. }
    88. </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 打造自己的个性化应用(二):应用程序内置资源实现换肤功能的更多相关文章

  1. 一种简单的实现:Android一键换肤功能

    现在的APP开发,通常会提供APP的换肤功能,网上流传的换肤代码和实现手段过于复杂,我把原作者的代码重新整理抽取出来,转换成Eclipse项目,重新整理成正确.可直接运行的项目. 代码运行结果如图. ...

  2. Android一键换肤功能:一种简单的实现

     Android一键换肤功能:一种简单的实现 现在的APP开发,通常会提供APP的换肤功能,网上流传的换肤代码和实现手段过于复杂,这里有一个开源实现,我找了一大堆,发现这个项目相对较为简洁:htt ...

  3. Android 打造自己的个性化应用(一):应用程序换肤主流方式的分析与概述

    Android平台api没有特意为换肤提供一套简便的机制,这可能是外国的软件更注重功能和易用,不流行换肤.系统不提供直接支持,只能自行研究. 换肤,可以认为是动态替换资源(文字.颜色.字体大小.图片. ...

  4. Android 换肤功能的实现(Apk插件方式)

    一.概述 由于Android 没有提供一套统一的换肤机制,我猜可能是因为国外更注重功能和体验的原因 所以国内如果要做一个漂亮的换肤方案,需要自己去实现. 目前换肤的方法大概有三种方案: (1)把皮肤资 ...

  5. Unit05: JavaScript对象概述 、 常用内置对象一 、 常用内置对象二 、 常用内置对象三

    Unit05: JavaScript对象概述 . 常用内置对象一 . 常用内置对象二 . 常用内置对象三 常用内置对象使用演示: <!DOCTYPE html> <html> ...

  6. Flex AIR应用换肤功能(Android和IOS)

    说明 换肤功能,即将整个应用的皮肤都进行更换,其实质,是动态加载swf文件的过程,而这些swf文件则有css文件编译而来. 关于换肤功能,在android和ios系统的实现方式是不同的.主要原因,是因 ...

  7. Android QMUI实战:实现APP换肤功能,并自动适配手机深色模式

    Android换肤功能已不是什么新鲜事了,市面上有很多第三方的换肤库和实现方案. 之所以选择腾讯的QMUI库来演示APP的换肤功能,主要原因: 1.换肤功能的实现过程较简单.容易理解: 2.能轻松适配 ...

  8. Android 打造自己的个性化应用(四):仿墨迹天气实现-->自定义扩展名的zip格式的皮肤

    在这里谈一下墨迹天气的换肤实现方式,不过首先声明我只是通过反编译以及参考了一些网上其他资料的方式推测出的换肤原理, 在这里只供参考. 若大家有更好的方式, 欢迎交流. 墨迹天气下载的皮肤就是一个zip ...

  9. Android 打造自己的个性化应用(三):应用程序的插件化

    在android的项目开发中,都会遇到后期功能拓展增强与主程序代码变更的现实矛盾,也就是程序的灵活度. 由于linux平台的安全机制,再加上dalvik的特殊机制,各种权限壁垒,使得开发一个灵活多变的 ...

随机推荐

  1. SQL Server常用脚本

    一.迁移登录用户脚本: select 'create login [' + p.name + '] ' + case when p.type in('U','G') then 'from window ...

  2. c# 鼠标操作

    1#region 3using System; 4using System.Runtime.InteropServices; 6#endregion 8namespace Windows.Forms. ...

  3. 页面全部加载完毕和页面dom树加载完毕

    dom树加载完毕 $(document).ready()//原生写法document.ready = function (callback) {            ///兼容FF,Google   ...

  4. 如何安装Windows Live Writer插件

    Windows Live Writer 是一个强大的离线博客编辑工具,通过它可以离线编辑内容丰富的博文.它不但支持微软的live space,还支持诸如Wordpress 这样的开源博客系统. Win ...

  5. ORACLE SQL单行函数(二)【weber出品必属精品】

    11.dual:虚表,任何用户都可以使用,表结构如下: SQL> desc dual Name Null? Type -------------------------------------- ...

  6. silverlight 生产图表(动态图表类型,Y轴数量) .xaml.cs文件

    silverlight 页面后台方法 .xaml.cs文件 public void CreateChart(Grid oGrid, ObservableCollection<ListItem&g ...

  7. 洛谷 P3395 路障

    P3395 路障 题目背景 此题约为NOIP提高组Day1T1难度. 题目描述 B君站在一个n*n的棋盘上.最开始,B君站在(1,1)这个点,他要走到(n,n)这个点. B君每秒可以向上下左右的某个方 ...

  8. Freemarker日期函数处理【转】

    Freemarker日期函数处理[转] (2012-08-01 14:32:13) 转载▼ 标签: 杂谈   string(当和一个日期值一起使用) 这个内置标签用指定的格式把日期转换成字符串,(把默 ...

  9. windows安装Apache HTTP服务器报错:无法启动,因为应用程序的并行配置不正确

    Apache HTTP服务器安装后报:无法启动,因为应用程序的并行配置不正确-(已解决)   0条评论 [摘要:本创做品,出自 “深蓝的blog” 专客,迎接转载,转载时请务必说明出处,不然有权穷究版 ...

  10. jquery之下拉列表select

    选择下拉列表中的一项,文本框显示其值 html代码如下: <select id="ttt"> <option value="Volvo" id ...