Android7.0(N)打开第三方app时StatusBar(状态栏)颜色变化流程浅析

    简介:当打开第三方App时,一般都是铺满整个屏幕,从而使得状态栏颜色发生变化,本文简单的分析下SystemUI方面StatusBar的Icon图标的颜色变化流程

    本文从CommandQueue类开始分析,源码位于

frameworks\base\packages\SystemUI\src\com\android\systemui\statusbar\CommandQueue.java
  public void appTransitionStarting(long startTime, long duration) {
        synchronized (mLock) {
            mHandler.removeMessages(MSG_APP_TRANSITION_STARTING);
            //发送一个MSG_APP_TRANSITION_STARTING消息
            mHandler.obtainMessage(MSG_APP_TRANSITION_STARTING, Pair.create(startTime, duration)) .sendToTarget();
        }
    }
mHander是CommandQueue中的一个内部类,主要用于消息的接收:
private final class H extends Handler {
        public void handleMessage(Message msg) {
            final int what = msg.what & MSG_MASK;
            switch (what) {
...........................................
case MSG_APP_TRANSITION_STARTING:
                    Pair data = (Pair) msg.obj;
                    mCallbacks.appTransitionStarting(data.first, data.second);
                    break;
......................
}
以上代码有部分省略,想深入研究的朋友可以查看源代码进行相应的分析。从上面可以看出对于消息的处理主要是回调mCallbacks的appTransitionSarting()函数;那么mCallbacks又是从哪传入呢?通过在SystemUI文件夹搜索,可以看出BaseStatusBar实现了CommandQueue.Callbacks,且在文件中有:
public void start() {
..............
   // Connect in to the status bar manager service
//CommandQueue的构造函数传入参数就是CallBacks的具体实现者,而PhoneStatusBar是BaseStatusBar的具体实现者
    mCommandQueue = new CommandQueue(this);
..............
}
由此转入到真正实现者PhoneStatusBar进行处理,其源码位于
frameworks\base\packages\SystemUI\src\com\android\systemui\statusbar\phone\PhoneStatusBar.java
 @Override
    public void appTransitionStarting(long startTime, long duration) {
        // Use own timings when Keyguard is going away, see keyguardGoingAway and
        // setKeyguardFadingAway.
      //解锁之后:mKeyguardGoingAway=false,所以走mIconController分支
        if (!mKeyguardGoingAway) {
            mIconController.appTransitionStarting(startTime, duration);
        }
        if (mIconPolicy != null) {
            mIconPolicy.appTransitionStarting(startTime, duration);
        }
    }
frameworks\base\packages\SystemUI\src\com\android\systemui\statusbar\phone\StatusBarIconController.java
 public void appTransitionStarting(long startTime, long duration) {
        if (mTransitionPending && mTintChangePending) {
            mTintChangePending = false;
         //状态栏图标颜色变化动画
            animateIconTint(mPendingDarkIntensity,
                    Math.max(0, startTime - SystemClock.uptimeMillis()),
                    duration);
} else if (mTransitionPending) {
            // If we don't have a pending tint change yet, the change might come in the future until
            // startTime is reached.
            mTransitionDeferring = true;
            mTransitionDeferringStartTime = startTime;
            mTransitionDeferringDuration = duration;
            mHandler.removeCallbacks(mTransitionDeferringDoneRunnable);
            mHandler.postAtTime(mTransitionDeferringDoneRunnable, startTime);
        }
        mTransitionPending = false;
    }
private void animateIconTint(float targetDarkIntensity, long delay,
            long duration) {
        if (mTintAnimator != null) {
            mTintAnimator.cancel();
        }
      if (mDarkIntensity == targetDarkIntensity) {
            return;
        }
        mTintAnimator = ValueAnimator.ofFloat(mDarkIntensity, targetDarkIntensity);
        mTintAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
 public void onAnimationUpdate(ValueAnimator animation) {
             /**
                 * 通过这样一个监听事件,我们就可以获取
                  * 到ValueAnimator每一步所产生的值。
                 *
                 * 通过调用getAnimatedValue()获取到每个时间因子所产生的Value。
                * */
                setIconTintInternal((Float) animation.getAnimatedValue());
            }
        });
        mTintAnimator.setDuration(duration);
        mTintAnimator.setStartDelay(delay);
        mTintAnimator.setInterpolator(Interpolators.FAST_OUT_SLOW_IN);
        mTintAnimator.start();
    }
  private void setIconTintInternal(float darkIntensity) {
        mDarkIntensity = darkIntensity;
       //mIconTint 图标颜色适配获取变量,默认为白色,在此是获取适配的颜色
        mIconTint = (int) ArgbEvaluator.getInstance().evaluate(darkIntensity,
                mLightModeIconColorSingleTone, mDarkModeIconColorSingleTone);
        mNotificationIconAreaController.setIconTint(mIconTint);
      //应用适配的颜色
        applyIconTint();
    }
在该函数中有个mIconTint颜色适配,主要是通过获取ArgbEvaluator的实例,通过其evaluate()函数计算出其过渡每一时段的颜色;
  mDarkModeIconColorSingleTone = context.getColor(R.color.dark_mode_icon_color_single_tone); //纯黑色
  mLightModeIconColorSingleTone = context.getColor(R.color.light_mode_icon_color_single_tone); //纯白色
即上述函数的含义是:通过获取ValueAnimator每一个过渡时段的时间因子Value,在纯白色和纯黑色之间计算出一个合适的颜色值mIconTint,来适配对应的状态栏颜色。
applyIconTint即完成对应的StatusBar的状态栏图标的颜色适配:
 private void applyIconTint() {
        for (int i = 0; i < mStatusIcons.getChildCount(); i++) {
            StatusBarIconView v = (StatusBarIconView) mStatusIcons.getChildAt(i);
            v.setImageTintList(ColorStateList.valueOf(getTint(mTintArea, v, mIconTint)));
        }
       mSignalCluster.setIconTint(mIconTint, mDarkIntensity, mTintArea);
        mBatteryMeterView.setDarkIntensity(
                isInArea(mTintArea, mBatteryMeterView) ? mDarkIntensity : 0);
        mClock.setTextColor(getTint(mTintArea, mClock, mIconTint));
    }









你可能感兴趣的:(android,SystemUI)