2 baidu 37299572 baidu_37299572 于 2017.01.12 10:16 提问

安卓如何自动更新资源文件?实现切换主题 皮肤

我想的实现方法是先设置好一个皮肤路径 然后imageView.setImageResource(loadfrompath/XXX.PNG)然后现在想直接把这个path改变实现换肤,想请教一下如何实现,在不重启的情况下,求指点。。。让这个imageView.setImageResource自动更新

3个回答

yangjiabei_0301
yangjiabei_0301   2017.01.12 10:51

如果你的皮肤图片文件是在项目的资源文件中存的,不是在数据库中存的
假如你有两套皮肤,你可以在数据库中设置一个开关字段,在程序中进行判断,
比如:
1.开关是TRUE的话展示默认的样式,开关是FALSE的话展示圣诞节的皮肤
你可以判断通过判断开关在程序自动的调用不同资源路径下的皮肤文件这是一个方法!这样依旧可以在不重启的情况下,手动该数据的开关,
实现皮肤的切换!
2.如果你对数据库不熟悉可以,或者其他的条件不允许你修改数据库,你也可以在程序中运用时间,判定在什么时候运用那套皮肤,
大致意思就是,判断系统时间在不在你需要的时间段内,在的话就调用圣诞节的皮肤,不在的话就调用默认的皮肤!这种方法不需要更改数据库,
也不需要改资源文件,缺点也很明显,你的项目要提前准备好所需要的资源文件,会增加你的项目体积,程序一旦写好了,就不能在动态的更改了!
3.一般我会采用的方式是,把皮肤用到的资源文件和开关同时存储在数据库中,把图片放在服务器上,通过请求服务的方式获取到本地,把默认的
皮肤文件和节日的或者其他的皮肤都放在数据库里,在客服端请求获取,这样就既减少可项目的体积,皮肤的配置也变得可以动态修改,需要改变
皮肤的时候只需要替换数据库中响应的文件就和改开关就行了!
我的大体实现方法是这样的,你可以根据你的具体环境看怎么处理!

baidu_37299572
baidu_37299572 嗯。。。现在我的问题是我把路径换了以后图片并没有更新,要重启才可以。。我是没有数据库的 通过加载不同的资源文件夹实现换肤,但是如果程序编译好了 这时候改拂去资源文件路径或者把原来读取的文件夹里的资源图片删了,UI是没有更新的
11 个月之前 回复
Kelley_cfy
Kelley_cfy   2017.01.12 14:20

实现皮肤干嘛要这样做, 你需要一个ThemeManager, 里面负责监听皮肤的更改, 一旦发生更改就会回调到每一个注册了监听的Activity中, 然后重新获取Drawable, 刷新显示

Kelley_cfy
Kelley_cfy 回复ZWate: 回复在下面
11 个月之前 回复
Kelley_cfy
Kelley_cfy 回复ZWate: 你可以先学习下插件的技术, 其实一个皮肤就是相当于一个资源包, 包里面有你所有需要的图片或者XML资源, 程序里只需要知道当前是哪个皮肤, 然后去读取指定皮肤资源包中的图片
11 个月之前 回复
baidu_37299572
baidu_37299572 一旦发生更改就会回调到每一个注册了监听的Activity中, 然后重新获取Drawable, 刷新显示,能简单用代码说明一下吗,怎么回掉怎么重新获取Drawable,求指点啊大神
11 个月之前 回复
Kelley_cfy
Kelley_cfy   2017.01.12 15:01

/**
* 获取某个Drawable 如果不存在则获取defaultResId的Drawable
* 默认的主题必须存在
* @param resId
* @param defaultResId 必须在主题中声明
* @return
*/
public Drawable getThemeDrawable(int resId, int defaultResId){
try{
if(isDefaultTheme()){
return mThemeResource.getDrawable(resId);
} else {
String name = mContext.getResources().getResourceEntryName(resId);
int id = mThemeResource.getIdentifier(name, "drawable", getCurrentTheme());
if(id > 0){
return mThemeResource.getDrawable(id);
} else{
String defaultResName = mContext.getResources().getResourceEntryName(defaultResId);
int themeDefaultResid = mThemeResource.getIdentifier(defaultResName, "drawable", getCurrentTheme());
return mThemeResource.getDrawable(themeDefaultResid);
}
}
} catch (Throwable e){
if(Loger.isD()){
Loger.i(getClass().getSimpleName(), " getDrawable " + e.getMessage());
}
}
return mContext.getResources().getDrawable(resId);
}
比如这样, 皮肤是一个APK资源包, 根据当前设置的皮肤获取到当前的Resources, 然后用ImageView.setImageDrawable(getThemeDrawable()), 当皮肤发生改变的时候再调用ImageView.setImageDrawable(getThemeDrawable())这个就会刷新显示, 至于怎么调用刷新, 你可以看看设计模式里面的观察者模式

Csdn user default icon
上传中...
上传图片
插入图片
准确详细的回答,更有利于被提问者采纳,从而获得C币。复制、灌水、广告等回答会被删除,是时候展现真正的技术了!