原文地址: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. Node.js 之 express 入门 ejs include公共部分

    1. 直接进入express安装 因为之前有一篇文章我已经讲过怎么安装node了 而网上的教程也是非常多.所有直接进入到express.教程简陋 由于我比较笨 所有只要写到我自己明白就行. 这里有个教 ...

  2. centos6.5配置无线网络

    由于安装的是服务器版,所以开机无法连接网络,以下这些情况都是针对驱动已经安装OK.按步骤操作如下(以下操作默认都是在超级管理员权限下进行): 1.测试电脑是否安装wpa_supplicant,测试方法 ...

  3. 通过JS控制textarea的输入长度

    废话不多说,直接上代码(因为自己也只是遇到的时候然后上网查到的解决办法,放在此处只是为了方便各位看以及以后再碰到用起来方便) <ul> <li> <textarea ro ...

  4. Javascript高级程序设计读书笔记(第三章)

    第3章 基本概念 3.4 数据类型 5种简单数据类型:undefined.boolean.number.null.string. typeof操作符,能返回下列某个字符串:“undefined”.“b ...

  5. JS属性读写操作+if判断注意事项

    js中不允许出现“ - ” 页面中改变文字大小-案例: <!doctype html> <html lang="en"> <head> < ...

  6. Asp.Net HttpApplication请求管道与Session(二)

    Asp.Net 回话的创建与结束 LogHelper.LogHelper _log = new LogHelper.LogHelper(); /// <summary> /// 程序开始- ...

  7. FileShare文件读写锁解决“文件XXX正由另一进程使用,因此该进程无法访问此文件”(转)

    开发过程中,我们往往需要大量与文件交互,读文件,写文件已成家常便饭,本地运行完美,但一上到投产环境,往往会出现很多令人措手不及的意外,或开发中的烦恼,因此,我对普通的C#文件操作做了一次总结,问题大部 ...

  8. C#中new和override的区别

    override是指“覆盖”,是指子类覆盖了父类的方法.子类的对象无法再访问父类中的该方法.(签名必须相同) new是指“隐藏”,是指子类隐藏了父类的方法,当然,通过一定的转换,可以在子类的对象中访问 ...

  9. centos打开3306端口

    centos默认是关闭了3306端口的,外网通过3306端口不能访问数据库,这时需呀打开3306端口1.打开端口: /sbin/iptables -I INPUT -p tcp --dport 330 ...

  10. Oracle 账户被锁定

    哎 每次安装oracle的时候总是忘了将用户解锁,结果就蛋疼了,从网上找到一个简单的解决方案 在CMD命令输出如下: sqlplus /nolog alert user system account ...