statusbar 更换图标UI 续

上篇文章我们已经找到我们要跟换图标的地方也即是SystemUI 模块
com.android.systemui/qs/tiles/下的XXXXTile 。在这里我们用飞行模式作为示例。

AirplaneModeTile类图大致如下:
这里写图片描述
我们只需要关注圈中的那些变量或者方法就可以,首先我们进入handUpdateState方法中,字面意思大家应该能猜到就是处理状态变化。
下面我们就来分析此方法,首先先看源码,我摘取了一些必要的

 @Override
    protected void handleUpdateState(BooleanState state, Object arg) {
        final int value = arg instanceof Integer ? (Integer)arg : mSetting.getValue();
        boolean airplaneMode = value != 0;
        ........
        if (airplaneMode) {//打开状态赋值
        state.icon = mEnable;
        state.contentDescription =  mContext.getString(                             R.string.accessibility_quick_settings_airplane_on);
        } else {//关闭状态赋值
        state.icon = mDisable;
        state.contentDescription =  mContext.getString(
        R.string.accessibility_quick_settings_airplane_off);
        }

    }

从源码可以看出分别对飞行模式下的打开和关闭两种状态做赋值操作,从而切换图片。这里我们如何换成自己的呢?

 state.icon = mEnable;
 查看state :BooleanState,是父类QSTile 的内部类
  public static class BooleanState extends State {
        public boolean value;

        @Override
        public boolean copyTo(State other) {
            final BooleanState o = (BooleanState) other;
            final boolean changed = super.copyTo(other) || o.value != value;
            o.value = value;
            return changed;
        }

        @Override
        protected StringBuilder toStringBuilder() {
            final StringBuilder rt = super.toStringBuilder();
            rt.insert(rt.length() - 1, ",value=" + value);
            return rt;
        }
    }
没有我们需要的Icon,追溯父类
 State :
 public static class State {
        ........
        public Icon icon;
        .......
    }
 Icon :
  public static abstract class Icon {
        abstract public Drawable getDrawable(Context context);

        @Override
        public int hashCode() {
            return Icon.class.hashCode();
        }
    }
    这里可以发现Icon 是一个抽象类,类型也就是一个Drawable。
这里我们在回到  AirplaneModeTile:

   private final AnimationIcon mEnable =
            new     AnimationIcon(R.drawable.ic_signal_airplane_enable_animation);
    state.icon = mEnable;
这里icon 是一个 AnimationIcon 
     protected class AnimationIcon extends ResourceIcon {
        private boolean mAllowAnimation;

        public AnimationIcon(int resId) {
            super(resId);//调用了ResourceIcon 
        }

        public void setAllowAnimation(boolean allowAnimation) {
            mAllowAnimation = allowAnimation;
        }

        @Override
        public Drawable getDrawable(Context context) {
            // workaround: get a clean state for every new AVD
            final AnimatedVectorDrawable d = (AnimatedVectorDrawable) super.getDrawable(context)
                    .getConstantState().newDrawable();
            d.start();
            if (mAllowAnimation) {
                mAllowAnimation = false;

            } else {
                d.stop(); // skip directly to end state
            }
            return d;
        }
    }

    ResourceIcon :
     public static class ResourceIcon extends Icon {
        private static final SparseArray<Icon> ICONS = new SparseArray<Icon>();

        private final int mResId;

        private ResourceIcon(int resId) {
            mResId = resId;
        }

        public static Icon get(int resId) {
            Icon icon = ICONS.get(resId);
            if (icon == null) {
                icon = new ResourceIcon(resId);
                ICONS.put(resId, icon);
            }
            return icon;
        }

        @Override
        public Drawable getDrawable(Context context) {
            return context.getDrawable(mResId);
        }

    }
    回到AnimationIcon 
     @Override
        public Drawable getDrawable(Context context) {
            // workaround: get a clean state for every new AVD
            final AnimatedVectorDrawable d = (AnimatedVectorDrawable) super.getDrawable(context)
                    .getConstantState().newDrawable();
            d.start();
            if (mAllowAnimation) {
                mAllowAnimation = false;

            } else {
                d.stop(); // skip directly to end state
            }
            return d;
        }
        这里是最主要的,应用了AnimatedVectorDrawable  动态矢量图
    ,这里我们先不看,可以做为特定的一点去学习。

到这里我们明白飞行模式的图标就是一个矢量图,因为目前我手上给的是图片,所以就不能简单的就替换
private final AnimationIcon mEnable =
new AnimationIcon(R.drawable.ic_signal_airplane_enable_animation);

为自己 的图标。这里怎么办呢?我们不需要动画,所以我们就找到AnimationIcon 的父亲ResourceIcon它的Drawable getDrawable()
就是我们要用到的所以我们就可以在AirplaneModeTile

 @Override
    protected void handleUpdateState(BooleanState state, Object arg) {
        final int value = arg instanceof Integer ? (Integer)arg : mSetting.getValue();
        boolean airplaneMode = value != 0;
        ........
        if (airplaneMode) {//打开状态赋值
        //加上自己的图标
        if(是换自己的UI)
        {
         state.icon = ResourceIcon.get(R.drawable.自己的图标);
        }else{
         state.icon = mEnable;
        }
        state.contentDescription =  mContext.getString(                             R.string.accessibility_quick_settings_airplane_on);
        } else {//关闭状态赋值
        //此处同理
        state.icon = mDisable;
        state.contentDescription =  mContext.getString(
        R.string.accessibility_quick_settings_airplane_off);
        }
    }

好了图标就换成功啦。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值