相比之前免安装的方式,这种方法需要用户下载并安装皮肤apk,程序写起来比免安装的要简单很多,像很多系统主题就是通过这种方式实现的。

这种方式的思路是,从所有已安装的应用程序中遍历出皮肤程序(根据特定包名区分),然后选中某个主题后,将此皮肤应用的包名保存到主应用中,需要获取资源时,通过皮肤包名得到皮肤应用的Context,然后便可得到Resources,从而获取到皮肤apk中的资源。下面看看关键步骤的代码:

遍历所有应用程序,筛选出皮肤应用程序

/**
 * 获取所有已安装的皮肤主题
 * @return
 */
private ArrayList<PackageInfo> getAllSkin() {
    ArrayList<PackageInfo> skinList = new ArrayList<PackageInfo>();
    List<PackageInfo> packs = getPackageManager().getInstalledPackages(0);
    for (PackageInfo p : packs) {
        if (isSkinPackage(p.packageName)) {
            skinList.add(p);
        }
    }
    return skinList;
}
/**
* 判断是否是皮肤主题
 */
private boolean isSkinPackage(String packageName) {
    String rex = Contact.SKIN_APP_PACKNAME+"\\w";
    Pattern pattern = Pattern.compile(rex);
    Matcher matcher = pattern.matcher(packageName);
    return matcher.find();
}

获取皮肤资源

此处需要注意一点,在拿到皮肤apk的Resources之后,获取资源的时候不能直接使用R.xx.xx,因为这个时候的R是主应用中的R,而不是皮肤apk中的R,如果主应用和皮肤apk的资源不一样(种类和数量),他们的R文件中的资源ID值是不一样的,这样就会找不到资源。可以通过getIdentifier方法根据资源名称获取资源ID,这样皮肤apk中的资源可以只有那些需要做改变的(并不需要和宿主应用中一模一样),并保持和宿主中资源名称相同即可。

private void changeSkin(){
    String skinPackName = mContext.getSharedPreferences(Contact.SP_NAME, Context.MODE_PRIVATE).getString(Contact.SP_KEY_SKIN, "");
    if(TextUtils.isEmpty(skinPackName)){
        //使用默认皮肤
        layout.setBackgroundDrawable(getResources().getDrawable(R.drawable.activity_bg));
    }else{
        //使用皮肤主题
        try {
            final Context context = createPackageContext(skinPackName, Context.CONTEXT_IGNORE_SECURITY);
            //此处应该根据皮肤apk中的资源ID找到皮肤资源,而不能直接用本应用中的R
            //如果皮肤资源和应用中的资源完全一样(数量和种类)才能直接使用应用中的R
            //layout.setBackgroundDrawable(context.getResources().getDrawable(R.drawable.activity_bg));
            Resources resources = context.getResources();
            int indentify = resources.getIdentifier(context.getPackageName()+":drawable/activity_bg", null, null);
            if(indentify>0){
                layout.setBackgroundDrawable(context.getResources().getDrawable(indentify));
            }
        } catch (NameNotFoundException e) {
            e.printStackTrace();
        }
    }
}

效果图:

源码下载:

https://github.com/openXu/SkinChange3

Android动态换肤(三、安装主题apk方式)的更多相关文章

  1. Android动态换肤(二、apk免安装插件方式)

    在上一篇文章Android动态换肤(一.应用内置多套皮肤)中,我们了解到,动态换肤无非就是调用view的setBackgroundResource(R.drawable.id)等方法设置控件的背景或者 ...

  2. Android动态换肤(一、应用内置多套皮肤)

    动态换肤在很多android应用中都有使用,用户根据自己的喜好设置皮肤主题,可以增强用户使用应用的舒适度. Android换肤可以分为很多种,它们从使用方式,用户体验以及项目框架设计上体现了明显的差异 ...

  3. element-ui 动态换肤

    1.在安装好 element-ui@2.x 以后,首先安装sass-loader npm i sass-loader node-sass -D 2.安装 element-theme npm i ele ...

  4. Android实现换肤功能(一)

    上周有个朋友给建议说讲讲换肤吧,真巧这周公司的工作安排也有这个需求,换的地方之多之繁,让人伤神死了.正所谓磨刀不误砍柴工,先磨下刀,抽出一个工具类,写了个关于换肤的简单demo. Android中换肤 ...

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

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

  6. duilib入门之贴图描述、类html文本描述、动态换肤、Dll插件、资源打包

    转载自duilib入门文档 贴图描述: Duilib的表现力丰富很大程度上得益于贴图描述的简单强大.Duilib的贴图描述分为简单模式和复杂模式两种. 简单模式使用文件名做为贴图描述内容,在这种方式下 ...

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

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

  8. hybird之web动态换肤实现

    前言 最近在重构个hybird(原生的壳包着Web页面)的UI框架,进行到了做换肤功能的阶段,所以这里是我思考的解决的方法. 预想 目前实现换肤的功能无非就两种做法. 1.写几个皮肤文件,然后切换使用 ...

  9. CocoStudio基础教程(4)骨骼动画的动态换肤

    1.概述 游戏中人物的状态会发生改变,而这种改变通常要通过局部的变化来表现出来.比如获得一件装备后人物形象的改变,或者战斗中武器.防具的损坏等.这些变化的实现就要通过动态换肤来实现. 2.运行到程序 ...

随机推荐

  1. [SDOI 2011]染色

    Description 题库链接 给定一棵有 \(n\) 个节点的无根树和 \(m\) 个操作,操作有 \(2\) 类: 将节点 \(a\) 到节点 \(b\) 路径上所有点都染成颜色 \(c\) : ...

  2. [HNOI2016]序列

    题目描述 给定长度为n的序列:a1,a2,...,an,记为a[1:n].类似地,a[l:r](1<=l<=r<=N)是指序 列:al,al+1,...,ar-1,ar.若1< ...

  3. 线性规划与网络流24题●09方格取数问题&13星际转移问题

    ●(做codevs1908时,发现测试数据也涵盖了1907,想要一并做了,但因为“技术”不佳,搞了一上午) ●09方格取数问题(codevs1907  方格取数3) 想了半天,也没成功建好图: 无奈下 ...

  4. 【网络流】【BZOJ1070】【SCOI2007】修车

    原题链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1070 题意:问你如何分配老司机使得每部车的等待时间之和最短. 解题思路:本题不易正做,考虑 ...

  5. hdu 5115(2014北京—dp)

    题意: 有一排狼,每只狼有一个伤害A,还有一个伤害B.杀死一只狼的时候,会受到这只狼的伤害A和这只狼两边的狼的伤害B的和.如果某位置的狼被杀,那么杀它左边的狼时就会收到来自右边狼的B,因为这两只狼是相 ...

  6. SPOJ COT(树上的点权第k大)

    Count on a tree Time Limit: 129MS   Memory Limit: 1572864KB   64bit IO Format: %lld & %llu Submi ...

  7. 【vijos1943】上学路上

    题目戳这里 描述 小雪与小可可吵架了,他们决定以后互相再也不理对方了.尤其是,他们希望以后上学的路上不会再相遇. 我们将他们所在城市的道路网视作无限大的正交网格图,每一个整数点 (x,y) 对应了一个 ...

  8. Ubuntu 16.04 LTS(入门一)国内快速更新软件源

    一.源文件位置 备份并替换/etc/apt/sources.list的源内容: 二.更改源文件内容 sudo gedit /etc/apt/sources.list deb http://mirror ...

  9. 腾讯笔试题:小Q硬币组合

    腾讯有一道机试题: 大概意思是: 小Q非常富有,拥有非常多的硬币,小Q的拥有的硬币是有规律的,对于所有的非负整数K,小Q恰好> 各有两个数值为2^k,的硬币,所以小Q拥有的硬币是1,1,2,2, ...

  10. Just for mysql

    mysql的下载与安装 由于学校开设了数据库专业,并且最近准备在做一个web端的设计,虽然本人是负责前端(当然,前端技术也很LOW),但因种种原因,准备开始学习数据库相关的知识,以mysql为例. 昨 ...