Android动态替换图标总结
现在淘宝,京东等App在节假日打开时,都是采用一套节假日的图标,这种不用发版本,又可以随着后台配置动态替换图标固然是很方便,体验很好的事情.
准备工作:全部按钮的不同状态改为纯图片实现.
现在很多应用的通知策略都是采用小红点提示,小红点可以单独画出来,与图标分离,单独控制隐藏.但是现在需要动态替换图标,小红点就不能与图片分离了,否则会导致红点位置不理想或红点被图标遮住等问题.为此,所有的状态都需要改为纯图片实现.
首页的tab,目前应用采用的是RadioButton + Fragment
的实现,为此,需要自定义RadioButton的selector.
定义attr.
//下面定义的state_new_message表示有新消息 <declare-styleable name="MessageRadioButton"> <attr name="state_new_message" format="boolean"/> </declare-styleable>
定义selector.
//xxx为你的包名 //为了配合state_checked,需要4张图片 <?xml version="1.0" encoding="utf-8"?> <selector xmlns:android="http://schemas.android.com/apk/res/android" xmlns:message="http://schemas.android.com/apk/res/xxx"> <item android:drawable="@drawable/icon_union_selected" android:state_checked="true" message:state_new_message="false"/> <item android:drawable="@drawable/icon_union_selected_new" android:state_checked="true" message:state_new_message="true"/> <item android:drawable="@drawable/icon_union_normal" android:state_checked="false" message:state_new_message="false"/> <item android:drawable="@drawable/icon_union_normal_new" android:state_checked="false" message:state_new_message="true"/> </selector>
重写RadioButton(ImageView等控件也同样适用).
public class MessageRadioButton extends RadioButton { //定义的状态 private static final int[] STATE_NEW_MESSAGE = {R.attr.state_new_message}; //是否有新消息 private boolean hasNewMessage; /** * 构造函数 **/ /** * 关键需要此函数,添加状态 **/ @Override protected int[] onCreateDrawableState(int extraSpace) { if (hasNewMessage) { final int[] drawableState = super.onCreateDrawableState(extraSpace + 1); mergeDrawableStates(drawableState, STATE_NEW_MESSAGE); return drawableState; } return super.onCreateDrawableState(extraSpace); } /** * 设置是否有新消息数 * @param newMessage, 是否有新消息数 */ public void setHasNewMessage(boolean newMessage) { if (hasNewMessage != newMessage) { hasNewMessage = newMessage; refreshDrawableState(); } } }
使用MessageRadioButton的setHasNewMessage()
方法即可以显示带小红点的图片.
即所有按钮改为图片实现.
创建Drawable对象
动态配置就是下载图片成功后,从文件中获取每个按钮的Drawable对象.但是实现时需要注意细节:
根据图片生成的Drawable对象即BitmapDrawable.
目前BitmapDrawable对应的构造函数未被弃用的还有
BitmapDrawable(Resources res, Bitmap bitmap) BitmapDrawable(Resources res, String path)
但使用
BitmapDrawable(Resources res, String path)
时发现在vivo手机上没有生效,所以还是推荐BitmapDrawable(Resources res, Bitmap bitmap)
方法.图片在使用时也需要区分dpi,对应
Bitmap.setDensity()
方法,参数为160的倍数.
selector对应的Drawable对象即StateListDrawable.
StateListDrawable.addState(int[] stateSet, Drawable drawable)
方法可以添加状态对应的drawable.//state_new_message为false listDrawable.addState(new int[]{-R.attr.state_new_message}, drawable); //state_new_message为true listDrawable.addState(new int[]{R.attr.state_new_message}, drawable);
listDrawable必须调用
setBounds()
方法才能显示.