您的位置:首页 > 移动开发 > Android开发

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

2016-04-12 17:05 302 查看
相比之前免安装的方式,这种方法需要用户下载并安装皮肤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

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: