原文地址:http://www.eoeandroid.com/thread-318159-1-1.html

现在大多数android应用都支持切换皮肤的功能。比如千千静听,墨迹天气等等。本文介绍两种切换皮肤的方法。
1.第一种是通过安装皮肤apk的方式。
当安装了皮肤apk包之后,主程序只需要读取皮肤apk包里的图片资源。就可以实现切换皮肤了。
要获取apk皮肤包里的图片资源,需要获取到皮肤apk包的上下文Context.
[mw_shl_code=java,true]  try {
   currentContext = context.createPackageContext(
   packageName, //packageName是对应皮肤apk包的包名。
   Context.CONTEXT_INCLUDE_CODE|Context.CONTEXT_IGNORE_SECURITY);
   
   } catch(Exception e) {
   e.printStackTrace();
   }[/mw_shl_code]
 
图片资源的名字和位置要一致。好比如整个界面的背景mainbg.jpg,在主程序和皮肤包apk的位置都在res\drawable-hdpi\mainbg.jpg.下。
然后通过下面这个方法:
[mw_shl_code=java,true]  public static Drawable getDrawable(Context context,String drawableName) throws NotFoundException {
   Drawable resultDrawable =null;
   Context ct =getSkinContext(context);
   try{
   int resid=getIdentifier2(ct,drawableName.trim(),"drawable");
   if(resid == 0){ 
   resid=getIdentifier2(context,drawableName.trim(),"drawable");
   resultDrawable=context.getResources().getDrawable(resid);
   }else{
   resultDrawable=ct.getResources().getDrawable(resid);
   }
   }catch(Exception e){
   e.printStackTrace();
   
   }
   return resultDrawable;
   }[/mw_shl_code]
就可以获取到对应的皮肤资源。
可以看到,首先是根据通过下面这个方法,获取到对应资源的id,然后再更加id获取到对应的图片资源。
[mw_shl_code=java,true]  public static int getIdentifier2(Context context,String name,String defType) throws NotFoundException{
   int result=0;
   try{
   result = context.getResources().getIdentifier(name, defType, context.getPackageName());
   }catch(Exception e){
   e.printStackTrace();
   
   }
   return result;
   }[/mw_shl_code]
然后再设置对应控件的drawable.就实现了切换皮肤。
因为皮肤apk包的上下文经常用到,因此我用一个静态变量保存了起来。假如在皮肤包apk里找不到对应的图片资源,就在主程序的图片资源里找,不至于图片找不到,让界面空白。
2.第二种方式是把所有图片资源放到一起,打成一个压缩包。应用的时候把图片解压到sd卡或者是应用的data目录下。
通过下面方法,得到图片资源的Drawable。在把Drawable 设置到控件上。
[mw_shl_code=java,true]public static Drawable createDrawableByPath(Context context,String imagePath){
try {

if(StringUtils.isNull(imagePath))return null;

Bitmap bm = BitmapFactory.decodeFile(imagePath);

bm.setDensity(context.getResources().getDisplayMetrics().DENSITY_HIGH);

Drawable dw = new BitmapDrawable(context.getResources(), bm);

return dw;

} catch (Exception e) { 
e.printStackTrace();
}catch (OutOfMemoryError ex) {
System.gc();
ex.printStackTrace(); 
} 
return null;
}[/mw_shl_code]

因为sd卡有时候会加载不成功。或者是根本没有sd卡。所有我把图片的压缩包直接解压到了

context.getFilesDir().getPath() + File.separator + "skin"+ File.separator下。
主程序只实现一个简单的换肤功能。就只有两个界面,一个是主界面,它的背景显示一个背景,就是各个皮肤。另外一个是设置皮肤界面。
点击后就到了设置皮肤的界面:
另外两个皮肤工程分别是晴天皮肤和夜晚皮肤。这两个工程非常简单,其实根本不需要activity。只需要把图片mainbg.jpg放到res\drawable-hdpi\mainbg.jpg.下。
另外两个闪电皮肤zip包和大雪皮肤zip包,我已经放到了主程序里。点击按钮就解压。
当然举例子少不了苍老师,呵呵。
当点击苍老师皮肤zip时,会模拟从网络下载zip包实现切换皮肤。
[mw_shl_code=java,true]  mProgressDialog = ProgressDialog.show(SetSkinActivity.this,
   "", 
   "正在下载苍老师...", true, false);
   
   handler.postDelayed(new Runnable() {
   
   @Override
   public void run() {
   try {
   mProgressDialog.cancel();
   Toast.makeText(SetSkinActivity.this, "苍老师下载完毕!", Toast.LENGTH_LONG).show();
   
   
   ZipUtil.unZip(getAssets().open("cang.zip"), 
   Constant.SKIN_DIR+"cang.zip", Constant.SKIN_DIR);
   
   Constant.setAppSkin(SetSkinActivity.this, SetSkinActivity.this.getPackageName());
   restartMain();
   
   } catch (IOException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
   }
   
   }
   }, 3000);
   [/mw_shl_code]
换肤效果:
 
 
 
 
 
 
最后是源码:
<ignore_js_op>

2.0.zip

6.5 MB, 下载次数: 137

Android应用切换皮肤功能实现的更多相关文章

  1. Android应用切换皮肤功能实现(二)

    原文地址http://www.apkbus.com/forum.php?mod=viewthread&tid=149034&highlight=%E7%9A%AE%E8%82%A4 上 ...

  2. android如何切换皮肤

    1.先定义attr文件 <?xml version="1.0" encoding="utf-8"?> <resources> <a ...

  3. Android 实现切换主题皮肤功能(类似于众多app中的 夜间模式,主题包等)

    首先来个最简单的一键切换主题功能,就做个白天和晚上的主题好了. 先看我们的styles文件: <resources> <!-- Base application theme. --& ...

  4. jQuery实现无刷新切换主题皮肤功能

    主题皮肤切换功能在很多网站和系统中应用,用户可以根据此功能设置自己喜欢的主题颜色风格,增强了用户体验.本文将围绕如何使用jQuery实现点击无刷新切换主题皮肤功能. 查看演示DEMO:https:// ...

  5. Android实现换肤功能(二)

    前两天写的上章关于换肤的功能获得了很好的反响,今天为大家介绍另一种方式.今天实现的策略也是网友建议的,然后我自己去写了个demo,大家自己评估下相比第一种方式的优势和劣势在哪里. 简单介绍下关于第一种 ...

  6. 仿iReader切换皮肤进度条

    仿iReader切换皮肤进度条 标签(空格分隔): 自定义View [TOC] 本以为使用paint.setXfermode(new PorterDuffXfermode(Mode.XOR));可以轻 ...

  7. 你真的有必要退出吗——再说Android程序的退出功能

    转自你真的有必要退出吗--再说Android程序的退出功能 搞Android开发有一段时间了,相信很多从Windows开发过来的Android程序员都习惯性地会跟我一样遇到过同一个问题:如何彻底退出程 ...

  8. 一键切换皮肤的解决思想及iframe嵌套时寻找下级iframe的方法

    项目中有个一键切换皮肤的功能,感觉还不错,记录下,就是各颜色样式设置起来太复杂了,不知道有没有更简便的方法: 1.切换皮肤结构层 <li title="<s:text name= ...

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

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

随机推荐

  1. Tomcat 原理篇

    TOMCAT 原理篇一.Tomcat 组成(Tomcat 由以下组件组成) 1.server a) Server是一个Catalina Servlet容器: b) Server 可以包含一个或多个se ...

  2. Dev GridControl,GridView 显示多行文本及合并相同单元格

    显示多行文本的方法 首先把gridcontrol的views的Optionsview里的RowAutoHeight设置为True 在In-place Editor Repository 里添加 Mem ...

  3. iocfont 网页图标字体以及使用方法

    在网页设计中使用图标字体(icon font)是件挺有新意的事情,使用图标字体能我们带来了一定的方便,比如在移动设备.Retina屏幕效果展示.兼容IE6/7浏览器以及能任意将图标放大缩小等,这些都是 ...

  4. MVC5富文本编辑器CKEditor配置CKFinder

    富文本编辑器CKEditor的使用 *:first-child { margin-top: 0 !important; } body>*:last-child { margin-bottom: ...

  5. UILabel 的使用,属性详解

    ·UILable是iPhone界面最基本的控件,主要用来显示文本信息. ·常用属性和方法有: .创建 CGRect rect = CGRectMake(, , , ); UILabel *label ...

  6. cocos2dx 音效 粒子 数据存储

    1.音效 引入头文件 #include "simpleAudioEngine.h" 命名空间 using namespace CocosDenshion; //创建一个背景 Siz ...

  7. uva Fire!

    算法:BFS Joe works in a maze. Unfortunately, portions of the maze have caught on fire, and the owner o ...

  8. MYSQL 磁盘临时表和文件排序

    因为Memory引擎不支持BOLB和TEXT类型,所以,如果查询使用了BLOB或TEXT列并且需要使用隐式临时表,将不得不使用MyISAM磁盘临时表,即使只有几行数据也是如此. 这会导致严重的性能开销 ...

  9. Java系列--目录

    因工作项目的需要,从C#转Java也有很长一段时间了,决定记载归纳一下这半年到底学了什么,到了一个什么程度,当然其间可能会有一些关于.NET的对比. 这是这个系列的目录,我准备按照我的归纳学习点来写, ...

  10. replace 全局替换 和 数组去空

    <script> /*var str = 'a,b,dhhhh,d'; str = str.replace(/h/g,'j'); alert(str);*/ </script> ...