原文地址: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. linux提取指定行至指定位置

    grep查找ERROR,定位位置 awk打印到指定行数 sed打印到文本末尾 awk打印到文本末尾 方法一 #!/bin/csh -f if(-f errorlog.rpt) then rm -rf ...

  2. 应用highcharts做直观数据统计

    最近在看上了统计类的东东,发现以前端图表神器:highcharts Highcharts是一款功能强大.开源.美观.图表丰富.兼容绝大多数浏览器的纯Js图表库,Highcharts支持的图表类型有直线 ...

  3. 限制内容长度(CSS,jQuery)

    CSS(宽度限制在100px之内,超出就会点点点) <style type="text/css"> p{width: 100px;display: inline-blo ...

  4. 让DIV垂直居中的几种办法

    1.使用CSS3 的伸缩盒布局 <!doctype html> <html> <head> <meta charset="utf-8"&g ...

  5. (转).net程序员转战android第三篇---登录模块之静态登录

    这一篇我将分2个部分记录登录界面,第一部分是静态登录, 这部分将如何从界面布局.控件使用.文件关系.数据验证.登陆实现等5小块记录. 第二部分是动态登录,这块会基于上面的4小块,在数据验证不是静态数据 ...

  6. 3 linux、windows环境---路径分隔符不同导致的问题

    问题:通常在eclipse,IntelliJ IDEA等进行代码编写时,程序中用到路径通常采用/job/test.properties或D:/job/test.properties等是形式作为文件路径 ...

  7. C#通过生成ini文件,记住用户关闭程序之前的选择+忽略跨线程检查

    1.在类的里面添加 //写配置文件 [DllImport("kernel32")] private static extern long WritePrivateProfileSt ...

  8. C#定义委托函数实现在别的窗体中操作主窗体中的SerialPort控件

    1.在主窗体(含有serialPort的窗体)中 //先定义委托 public delegate void OpenPort(); public delegate void ClosePort(); ...

  9. 最小日志量的insert操作

    --1.实验环境 SQL> conn scott/tiger Connected to Oracle Database 11g Enterprise Edition Release 11.2.0 ...

  10. python3.4控制用户输入与输出

    一.输入 1.函数格式:input() 2.函数功能:接受一个标准输入数据,返回string类型.ctrl+z结束输入. 3.实例: 默认input():等待一个任意字符的输入 str=input(‘ ...