android 换肤换主题(apk包方式)

更换皮肤的方式有很多种,有更换背景图片的(图片来源于程序资源文件、sdCard、网络下载)、有更换theme样式的、也有apk的等等。

用apk的方式更换程序皮肤,这样的方式,方便,简单,而且使主程序的apk包较小。

先下载皮肤apk包,安装,然后使现在的程序读取新安装的apk包中的资源文件,下次再打开程序时,依旧读取的是上次设置的apk的资源,如果主题apk被卸载,那么就读取的是默认的资源。

核心代码(完整代码见项目压缩包)如下:

主程序:

读取已经安装了的皮肤包的包名、应用图标和应用名称,当然最重要的实包名,这样可以通过包名,去读取当前皮肤包中的其它资源的资源名称,从而去加载。

private RunnableserachSkin = new Runnable() {

@Override

void run() {

PackageManager manager = context.getPackageManager();

List<PackageInfo> packages = manager.getInstalledPackages(PackageManager.PERMISSION_GRANTED);

List<PackageInfo> skins = new ArrayList<PackageInfo>();

(PackageInfo info : packages) {// 遍历已经安装的皮肤包

(info.packageName.startsWith("com.theme.")) {// 与皮肤包的包名对应即可

skins.add(info);

}

}

(skins.size() > 0) {

Message msg = mHandler.obtainMessage();

msg.obj = skins;

msg.setData(new Bundle());

msg.what =MESSAGE_SEARCHED_SKIN;

.sendMessage(msg);

} else {

mHandler.sendEmptyMessage(MESSAGE_SEARCHED_SKIN_FOR_NONTHING);

}

}

};

this.setOnThemeChangedListener(new OnThemeChangedListener() {

@Override

onChanged(String themePackageName) {

Log.i("","themePackageName :: " + themePackageName);

{

Context themeContext = ThemeSecondActivity.this.createPackageContext(themePackageName, Context.CONTEXT_IGNORE_SECURITY);

Resources themeResources = themeContext.getResources();

setControlsStyle(themePackageName, themeResources);

} catch (NameNotFoundException e) {

e.printStackTrace();

}

}

});

/**

* 设置控件新皮肤

* @param themePackageName 皮肤包的包名

* @param themeResources 皮肤包的资源

*/

privatevoid setControlsStyle(String themePackageName, Resources themeResources) {

Log.i("", "themePackageName :: " + themePackageName);

.setBackground(themeResources.getDrawable(themeResources.getIdentifier("button_selector",

.setBackgroundColor(themeResources.getColor(themeResources.getIdentifier("background_gridview","color", themePackageName)));

}

找了很久的apk换肤,类似新浪微博或者QQ换肤,找到的案例只是简单的在当前项目中更换主题,,或者是apk包,但放置到自己的项目中时,抛出空指针或者资源文件不存在的异常。

纠其原因,因为资源文件没有找到,在当前项目中用的是getDrawable(R.drawable.xx)方式来获取图片,这种方式是根据R.drawable.xx对应的一个int值(int值在工程中的gen文件夹下的R.java的class类中)来识别并加载的,这样要确保主工程与皮肤工程对应的两个值是一样的,如果不一样,就可能出现错位(int值对应到其它的资源),当然还有可能导致空指针或者找不到资源文件(int值不存在)。

决解方式是,确保当前读取的res资源是皮肤包的资源,读取方式是:

Context themeContext = ThemeSecondActivity.this.createPackageContext(themePackageName,Context.CONTEXT_IGNORE_SECURITY);

Resources themeResources = themeContext.getResources();

项目压缩包下载地址:

说明:apk方式更换主题:包括多个页面更换,多个资源更换(可以颜色值、图片、xml文件等自定义资源文件)。 压缩中中包括4个工程,说明如下: SkinTheme是主工程,SkinRed是红色主题包,SkinGreen是绿色主题包,SkinBlue是蓝色主题包。

参考:

朋友,为了幸福,请你保持一副热爱生活的心肠,

android 换肤换主题(apk包方式)

相关文章:

你感兴趣的文章:

标签云: