这个是我在发版前几天才知道的一个需求。
其实不用 Firebase 也是可以完成的,但肯定要增加我们服务器的工作量的。
毕竟一个创业公司,还是需要注意资源合理利用,于是我还是找到了可靠的 Firebase.
需求
在65eday 的时候,需要把我们 主页 tab 的图标给替换了,包括文字。
脑补京东淘宝等。
接口设计
如果是这样的话,那我为了满足后期的类似需求,肯定是需要下发图片 url 下去,一劳永逸。
于是我让 Firebase配置了一个 json字符串,Android 拿到字符串去解析,然后再去做替换。
{
"isDefault": false,//是否显示默认的 true显示默认
"shop": {
"iconCheckedUrl": "",//选中的图片
"iconUrl": "",//默认图片
"name": "ezbuy"//tab 名称
},
"surf": {
"iconCheckedUrl": "http://upload-images.jianshu.io/upload_images/1432234-969054a168834d9d.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240",
"iconUrl": "http://upload-images.jianshu.io/upload_images/1432234-4ffd3e7a31471427.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240",
"name": "is"
},
"prime": {
"iconCheckedUrl": "http://upload-images.jianshu.io/upload_images/1432234-969054a168834d9d.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240",
"iconUrl": "http://upload-images.jianshu.io/upload_images/1432234-4ffd3e7a31471427.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240",
"name": ""
},
"cart": {
"iconCheckedUrl": "http://upload-images.jianshu.io/upload_images/1432234-969054a168834d9d.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240",
"iconUrl": "http://upload-images.jianshu.io/upload_images/1432234-4ffd3e7a31471427.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240",
"name": "the"
},
"mine": {
"iconCheckedUrl": "http://upload-images.jianshu.io/upload_images/1432234-969054a168834d9d.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240",
"iconUrl": "http://upload-images.jianshu.io/upload_images/1432234-4ffd3e7a31471427.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240",
"name": "best"
}
}
实现
Firebase 远程配置
java bean
Android Studio 可以根据json一键生成。
public class TabIconEntity {
/**
* shop : {"iconUrl":"","iconCheckedUrl":"","name":""}
* surf : {"iconUrl":"","iconCheckedUrl":"","name":""}
* prime : {"iconUrl":"","iconCheckedUrl":"","name":""}
* cart : {"iconUrl":"","iconCheckedUrl":"","name":""}
* mine : {"iconUrl":"","iconCheckedUrl":"","name":""}
*/
private TabBean shop;
private TabBean surf;
private TabBean prime;
private TabBean cart;
private TabBean mine;
private boolean isDefault;
public static class TabBean {
/**
* iconUrl :
* iconCheckedUrl :
* name :
*/
private String iconUrl;
private String iconCheckedUrl;
private String name;
public String getIconUrl() {
return iconUrl;
}
public void setIconUrl(String iconUrl) {
this.iconUrl = iconUrl;
}
public String getIconCheckedUrl() {
return iconCheckedUrl;
}
public void setIconCheckedUrl(String iconCheckedUrl) {
this.iconCheckedUrl = iconCheckedUrl;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
获取图片替换
首先会在闪屏页获取 Firebase Remote Config 配置(配置的不仅仅是只有这个,还有很多,统一获取回缓存)
/**
* 使用到远程配置的参数 在这里更新。
*/
public void getFirebaseRemoteConfig() {
final FirebaseRemoteConfig mFirebaseRemoteConfig = FirebaseRemoteConfig.getInstance();
FirebaseRemoteConfigSettings configSettings = new FirebaseRemoteConfigSettings.Builder()
.setDeveloperModeEnabled(BuildConfig.DEBUG)
.build();
mFirebaseRemoteConfig.setConfigSettings(configSettings);
mFirebaseRemoteConfig.setDefaults(R.xml.remote_config_defaults);
long cacheExpiration = 3600; // 1 hour in seconds.
// If in developer mode cacheExpiration is set to 0 so each fetch will retrieve values from
// the server.
if (mFirebaseRemoteConfig.getInfo().getConfigSettings().isDeveloperModeEnabled()) {
cacheExpiration = 0;
}
mFirebaseRemoteConfig.fetch(cacheExpiration)
.addOnCompleteListener(new OnCompleteListener() {
@Override
public void onComplete(@NonNull Task task) {
if (task.isSuccessful()) {
mFirebaseRemoteConfig.activateFetched();
}
}
});
}
然后再需要替换 icon 的页面加入以下代码就可以了
private void checkFirebaseTabIcon() {
drawables = new Drawable[5][];
String json = FirebaseRemoteConfig.getInstance().getString("tab_icon_json");
Gson gson = new Gson();
TabIconEntity entity = gson.fromJson(json, TabIconEntity.class);
if (entity != null && !entity.isDefault()) {//
addFirebaseIcon(entity.getShop(), shopButton, 0);
addFirebaseIcon(entity.getSurf(), surfButton, 1);
addFirebaseIcon(entity.getPrime(), primeButton, 2);
addFirebaseIcon(entity.getCart(), cartButton, 3);
addFirebaseIcon(entity.getMine(), mineButton, 4);
}
}
private void addFirebaseIcon(final TabIconEntity.TabBean bean, final RadioButton button, final int i) {
drawables[i] = new Drawable[2];
RequestQueue mQueue = Volley.newRequestQueue(getActivity());
ImageRequest request = new ImageRequest(bean.getIconUrl(), new Response.Listener() {
@Override
public void onResponse(Bitmap response) {
drawables[i][0] = new BitmapDrawable((response));
if (drawables[i][1] != null) {
addState(button, bean.getName(), i);
}
}
}, 0, 0, Bitmap.Config.ARGB_8888, null);
ImageRequest request1 = new ImageRequest(bean.getIconCheckedUrl(), new Response.Listener() {
@Override
public void onResponse(Bitmap response) {
drawables[i][1] = new BitmapDrawable((response));
if (drawables[i][0] != null) {
addState(button, bean.getName(), i);
}
}
}, 0, 0, Bitmap.Config.ARGB_8888, null);
mQueue.add(request);
mQueue.add(request1);
}
private void addState(RadioButton button, String name, int i) {
StateListDrawable sd = new StateListDrawable();
int px = DensityUtils.dp2px(getActivity(), 20);
if (i == 2) {//Prime 大一倍
px = px * 2;
}
sd.setBounds(0, 0, px, px);
int checked = android.R.attr.state_checked;
sd.addState(new int[]{-checked}, drawables[i][0]);
sd.addState(new int[]{checked}, drawables[i][1]);
button.setCompoundDrawables(null, sd, null, null);
if (!TextUtils.isEmpty(name)) {
button.setText(name);
}
}
启动 app 之后检测需要替换
注意
-图片20dp大小
-宽高 1:1
-prime 是 40dp*40dp
-prime 不要 name
样本图
注意点
1.拿到 url 然后先去下载图片,转成Drawable
2.利用StateListDrawable 设置selector
3.button.setCompoundDrawables(null, sd, null, null);利用这个 api 设置在RadioButton上面。
然后顺利完成了需求,并且不增加服务器的压力。产品可以随意配置了。