Android动态换肤(三、安装主题apk方式)

相比之前免安装的方式,这种方法需要用户下载并安装皮肤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
这里写图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

open-Xu

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值