BarTransitions.java revision 56d007b99841f7f603e5d5bc5c23b94c010f1945
1/* 2 * Copyright (C) 2013 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package com.android.systemui.statusbar.phone; 18 19import android.animation.TimeInterpolator; 20import android.app.ActivityManager; 21import android.content.Context; 22import android.content.res.Resources; 23import android.graphics.Canvas; 24import android.graphics.Color; 25import android.graphics.ColorFilter; 26import android.graphics.PixelFormat; 27import android.graphics.Rect; 28import android.graphics.drawable.Drawable; 29import android.os.SystemClock; 30import android.util.Log; 31import android.view.View; 32import android.view.animation.LinearInterpolator; 33 34import com.android.systemui.R; 35 36public class BarTransitions { 37 private static final boolean DEBUG = false; 38 private static final boolean DEBUG_COLORS = false; 39 40 public static final int MODE_OPAQUE = 0; 41 public static final int MODE_SEMI_TRANSPARENT = 1; 42 public static final int MODE_TRANSLUCENT = 2; 43 public static final int MODE_LIGHTS_OUT = 3; 44 45 public static final int LIGHTS_IN_DURATION = 250; 46 public static final int LIGHTS_OUT_DURATION = 750; 47 public static final int BACKGROUND_DURATION = 200; 48 49 private final String mTag; 50 private final View mView; 51 private final boolean mSupportsTransitions = ActivityManager.isHighEndGfx(); 52 private final BarBackgroundDrawable mBarBackground; 53 54 private int mMode; 55 56 public BarTransitions(View view, int gradientResourceId) { 57 mTag = "BarTransitions." + view.getClass().getSimpleName(); 58 mView = view; 59 mBarBackground = new BarBackgroundDrawable(mView.getContext(), gradientResourceId); 60 if (mSupportsTransitions) { 61 mView.setBackground(mBarBackground); 62 } 63 } 64 65 public int getMode() { 66 return mMode; 67 } 68 69 public void transitionTo(int mode, boolean animate) { 70 if (mMode == mode) return; 71 int oldMode = mMode; 72 mMode = mode; 73 if (DEBUG) Log.d(mTag, String.format("%s -> %s animate=%s", 74 modeToString(oldMode), modeToString(mode), animate)); 75 if (mSupportsTransitions) { 76 onTransition(oldMode, mMode, animate); 77 } 78 } 79 80 protected void onTransition(int oldMode, int newMode, boolean animate) { 81 applyModeBackground(oldMode, newMode, animate); 82 } 83 84 protected void applyModeBackground(int oldMode, int newMode, boolean animate) { 85 if (DEBUG) Log.d(mTag, String.format("applyModeBackground oldMode=%s newMode=%s animate=%s", 86 modeToString(oldMode), modeToString(newMode), animate)); 87 mBarBackground.applyModeBackground(oldMode, newMode, animate); 88 } 89 90 public static String modeToString(int mode) { 91 if (mode == MODE_OPAQUE) return "MODE_OPAQUE"; 92 if (mode == MODE_SEMI_TRANSPARENT) return "MODE_SEMI_TRANSPARENT"; 93 if (mode == MODE_TRANSLUCENT) return "MODE_TRANSLUCENT"; 94 if (mode == MODE_LIGHTS_OUT) return "MODE_LIGHTS_OUT"; 95 throw new IllegalArgumentException("Unknown mode " + mode); 96 } 97 98 public void finishAnimations() { 99 mBarBackground.finishAnimation(); 100 } 101 102 public void setContentVisible(boolean visible) { 103 // for subclasses 104 } 105 106 private static class BarBackgroundDrawable extends Drawable { 107 private final int mOpaque; 108 private final int mSemiTransparent; 109 private final Drawable mGradient; 110 private final TimeInterpolator mInterpolator; 111 112 private int mMode = -1; 113 private boolean mAnimating; 114 private long mStartTime; 115 private long mEndTime; 116 117 private int mGradientAlpha; 118 private int mColor; 119 120 private int mGradientAlphaStart; 121 private int mColorStart; 122 123 public BarBackgroundDrawable(Context context, int gradientResourceId) { 124 final Resources res = context.getResources(); 125 if (DEBUG_COLORS) { 126 mOpaque = 0xff0000ff; 127 mSemiTransparent = 0x7f0000ff; 128 } else { 129 mOpaque = res.getColor(R.color.system_bar_background_opaque); 130 mSemiTransparent = res.getColor(R.color.system_bar_background_semi_transparent); 131 } 132 mGradient = res.getDrawable(gradientResourceId); 133 mInterpolator = new LinearInterpolator(); 134 } 135 136 @Override 137 public void setAlpha(int alpha) { 138 // noop 139 } 140 141 @Override 142 public void setColorFilter(ColorFilter cf) { 143 // noop 144 } 145 146 @Override 147 protected void onBoundsChange(Rect bounds) { 148 super.onBoundsChange(bounds); 149 mGradient.setBounds(bounds); 150 } 151 152 public void applyModeBackground(int oldMode, int newMode, boolean animate) { 153 if (mMode == newMode) return; 154 mMode = newMode; 155 mAnimating = animate; 156 if (animate) { 157 long now = SystemClock.elapsedRealtime(); 158 mStartTime = now; 159 mEndTime = now + BACKGROUND_DURATION; 160 mGradientAlphaStart = mGradientAlpha; 161 mColorStart = mColor; 162 } 163 invalidateSelf(); 164 } 165 166 @Override 167 public int getOpacity() { 168 return PixelFormat.TRANSLUCENT; 169 } 170 171 public void finishAnimation() { 172 if (mAnimating) { 173 mAnimating = false; 174 invalidateSelf(); 175 } 176 } 177 178 @Override 179 public void draw(Canvas canvas) { 180 int targetGradientAlpha = 0, targetColor = 0; 181 if (mMode == MODE_TRANSLUCENT) { 182 targetGradientAlpha = 0xff; 183 } else if (mMode == MODE_SEMI_TRANSPARENT) { 184 targetColor = mSemiTransparent; 185 } else { 186 targetColor = mOpaque; 187 } 188 if (!mAnimating) { 189 mColor = targetColor; 190 mGradientAlpha = targetGradientAlpha; 191 } else { 192 final long now = SystemClock.elapsedRealtime(); 193 if (now >= mEndTime) { 194 mAnimating = false; 195 mColor = targetColor; 196 mGradientAlpha = targetGradientAlpha; 197 } else { 198 final float t = (now - mStartTime) / (float)(mEndTime - mStartTime); 199 final float v = Math.max(0, Math.min(mInterpolator.getInterpolation(t), 1)); 200 mGradientAlpha = (int)(v * targetGradientAlpha + mGradientAlphaStart * (1 - v)); 201 mColor = Color.argb( 202 (int)(v * Color.alpha(targetColor) + Color.alpha(mColorStart) * (1 - v)), 203 (int)(v * Color.red(targetColor) + Color.red(mColorStart) * (1 - v)), 204 (int)(v * Color.green(targetColor) + Color.green(mColorStart) * (1 - v)), 205 (int)(v * Color.blue(targetColor) + Color.blue(mColorStart) * (1 - v))); 206 } 207 } 208 if (mGradientAlpha > 0) { 209 mGradient.setAlpha(mGradientAlpha); 210 mGradient.draw(canvas); 211 } 212 if (Color.alpha(mColor) > 0) { 213 canvas.drawColor(mColor); 214 } 215 if (mAnimating) { 216 invalidateSelf(); // keep going 217 } 218 } 219 } 220} 221