anroid主题更换详解

项目需要进行主题更换,防Go桌面那样以apk形式进行主题更换,到网上找了下资料,资料不多,所以把自己学习的东西整理一下,以便以后查阅,同时也希望能帮到有需要的人:

一、网上找到的

网址:http://edison-cool911.iteye.com/blog/991048

这个方法要求主题apk中的资源id和应用资源id完全相同,如果应用资源多的话,会出现主题包偏大的情况。

二、我的方法

首先跟上面的一样,用context = createPackageContext(packageName,

CONTEXT_IGNORE_SECURITY);创建一个主题apkcontext,再用context得到resources用Resources类的getIdentifier(name, defType, defPackage)方法,该方法是得到对应名称的资源的id如果资源不存在则返回0:

Name:对应的资源名称(如资源R.drawable.ic_launcher--->name为“ic_launcher”)

defType:对应资源的类型(如资源R.drawable.ic_launcher--->defType为“drawable”)

defPackage:主题apk的包名

有了这个方法就可以用下面的代码取得主题包中的资源:

if (resId == 0) {
			// 图片不存在,使用默认图片
			Resources res = skinContext.getResources();
			int id = res.getIdentifier(drawableName, "drawable",
					skinInfo.context.getPackageName());
			drawable = res.getDrawable(id);
		} else {
			// 图片存在
			Resources res = skinInfo.skinContext.getResources();
			drawable = res.getDrawable(R.drawable.xxx);
		}


还有一个会用到的selector,所以要用程序实现selector,这就要用到StateListDrawable这个类

通过上面的方法得到selector中对应的资源,再通过下面的方法得到selector

public static StateListDrawable newSelector(Drawable pressed,
			Drawable focused, Drawable normal) {
		StateListDrawable states = new StateListDrawable();
		states.addState(new int[] { android.R.attr.state_pressed }, pressed);
		states.addState(new int[] { android.R.attr.state_focused }, focused);
		states.addState(new int[] { -android.R.attr.state_pressed }, normal);


		return states;
	}


用viewsetBackgroundDrawable()把上面方法的返回设置进去就可以了。。。

三、关于列出已安装的主题

我的方法:主题包取一个特定前缀的包名,通过遍历安装包得到特定前缀的包,再检查一下包的签名(关于签名检查,我的代码收藏里面有,百度一下也好多)



你可能感兴趣的:(android,android)