原文地址: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] 换肤效果: 最后是源码: |
Android, 加密, 皮肤
<ignore_js_op>
-
2.0.zip
6.5 MB, 下载次数: 137