版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/yuan7016/article/details/86605689
公司的老项目底部导航使用的是RadioButton + Fragment框架,最近有个新需求需要动态改变底部导航的样式,搜了很多文章都不太理想。最后就在准备放弃的时候,想到了Glide 可以把图片Url转为Drawable,拿到Drawable 后用代码写个selector,然后给RadioButton设置上去就行了,准备就绪,开干。
/**
* 设置底部导航 RadioButton 的selector
* @param radioButton
* @param normalUrl 默认图标URl
* @param checkedUrl 选中图标URL
*/
private void setRadioButtonSelectorDrawable(RadioButton radioButton, String normalUrl, String checkedUrl){
StateListDrawable stateListDrawable = new StateListDrawable();
//先加载默认样式
Glide.with(this)
.load(normalUrl)
.into(new SimpleTarget<Drawable>() {
@Override
public void onResourceReady(Drawable resource, Transition<? super Drawable> transition) {
//默认样式
stateListDrawable.addState(new int[]{-android.R.attr.state_checked},resource);
}
});
Glide.with(this)
.load(checkedUrl)
.into(new SimpleTarget<Drawable>() {
@Override
public void onResourceReady(Drawable resource, Transition<? super Drawable> transition) {
//选中的样式
stateListDrawable.addState(new int[]{android.R.attr.state_checked},resource);
}
});
//给RadioButton设置selector 对应xml布局里的android:drawableTop 属性
radioButton.setCompoundDrawablesWithIntrinsicBounds(null,stateListDrawable,null,null);
}
写完迫不及待开始测试,(翻车了。。。)发现并没有实现改变样式,又是一顿分析,最后发现stateListDrawable 这个selector没有起作用,就那就是Url转Drawable有问题了。后来想起Glide是异步加载,两个图标的加载可能没有先后顺序,导致 onResoureceReady方法可能在
radioButton.setCompoundDrawablesWithIntrinsicBounds(null,stateListDrawable,null,null) 方法之后才加载完成。
找到原因后解决问题,需要等两个图标Url加载后再调用
addState(int[] stateSet, Drawable drawable) 方法 ;
这时候就需要Rxjava2 了,当第一个图标加载完成后再加载第二个,等第二个加载完成后再给RadioButton设置selector,看代码:
/**
* 设置底部导航 RadioButton 的selector
* @param radioButton
* @param normalUrl 默认图标URl
* @param checkedUrl 选中图标URL
*/
private void setRadioButtonSelectorDrawable(RadioButton radioButton,String normalUrl,String checkedUrl){
StateListDrawable stateListDrawable = new StateListDrawable();
Observable.create(new ObservableOnSubscribe<Drawable>() {
@Override
public void subscribe(ObservableEmitter<Drawable> emitter) throws Exception {
//先加载默认样式
Glide.with(MainActivity.this)
.load(normalUrl)
.into(new SimpleTarget<Drawable>() {
@Override
public void onResourceReady(Drawable resource, Transition<? super Drawable> transition) {
emitter.onNext(resource);
emitter.onComplete();
}
});
}
}).subscribeOn(AndroidSchedulers.mainThread())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Observer<Drawable>() {
@Override
public void onSubscribe(Disposable d) {
}
@Override
public void onNext(Drawable normalDrawable) {
stateListDrawable.addState(new int[]{-android.R.attr.state_checked},normalDrawable);
}
@Override
public void onError(Throwable e) {
e.printStackTrace();
}
@Override
public void onComplete() {
//再加载选中的样式
Glide.with(MainActivity.this)
.load(checkedUrl)
.into(new SimpleTarget<Drawable>() {
@Override
public void onResourceReady(Drawable resource, Transition<? super Drawable> transition) {
stateListDrawable.addState(new int[]{android.R.attr.state_checked},resource);
//给RadioButton设置selector 对应xml布局里的android:drawableTop 属性
radioButton.setCompoundDrawablesWithIntrinsicBounds(null,stateListDrawable,null,null);
}
});
}
});
}
搞完测试,完美实现RadioButton动态改变图标样式效果。
效果如图:1.没改变前的底部导航:
2.改变后的底部导航: