NavigationBarTransitions.java revision ea56251d92050e9a672d1f66d0d4621e4dd4136e
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.Animator; 20import android.animation.AnimatorListenerAdapter; 21import android.content.Context; 22import android.os.ServiceManager; 23import android.view.MotionEvent; 24import android.view.View; 25import android.view.animation.AccelerateInterpolator; 26 27import com.android.internal.statusbar.IStatusBarService; 28import com.android.systemui.R; 29import com.android.systemui.statusbar.policy.KeyButtonView; 30 31public final class NavigationBarTransitions extends BarTransitions { 32 33 private static final float KEYGUARD_QUIESCENT_ALPHA = 0.5f; 34 private static final int CONTENT_FADE_DURATION = 200; 35 36 private final NavigationBarView mView; 37 private final IStatusBarService mBarService; 38 39 private boolean mLightsOut; 40 private boolean mVertical; 41 private int mRequestedMode; 42 43 public NavigationBarTransitions(NavigationBarView view) { 44 super(view, R.drawable.nav_background); 45 mView = view; 46 mBarService = IStatusBarService.Stub.asInterface( 47 ServiceManager.getService(Context.STATUS_BAR_SERVICE)); 48 } 49 50 public void init(boolean isVertical) { 51 setVertical(isVertical); 52 applyModeBackground(-1, getMode(), false /*animate*/); 53 applyMode(getMode(), false /*animate*/, true /*force*/); 54 } 55 56 public void setVertical(boolean isVertical) { 57 mVertical = isVertical; 58 transitionTo(mRequestedMode, false /*animate*/); 59 } 60 61 @Override 62 public void transitionTo(int mode, boolean animate) { 63 mRequestedMode = mode; 64 if (mVertical && (mode == MODE_TRANSLUCENT || mode == MODE_TRANSPARENT)) { 65 // translucent mode not allowed when vertical 66 mode = MODE_OPAQUE; 67 } 68 super.transitionTo(mode, animate); 69 } 70 71 @Override 72 protected void onTransition(int oldMode, int newMode, boolean animate) { 73 super.onTransition(oldMode, newMode, animate); 74 applyMode(newMode, animate, false /*force*/); 75 } 76 77 private void applyMode(int mode, boolean animate, boolean force) { 78 // apply to key buttons 79 final float alpha = alphaForMode(mode); 80 setKeyButtonViewQuiescentAlpha(mView.getHomeButton(), alpha, animate); 81 setKeyButtonViewQuiescentAlpha(mView.getRecentsButton(), alpha, animate); 82 setKeyButtonViewQuiescentAlpha(mView.getMenuButton(), alpha, animate); 83 84 setKeyButtonViewQuiescentAlpha(mView.getSearchLight(), KEYGUARD_QUIESCENT_ALPHA, animate); 85 86 applyBackButtonQuiescentAlpha(mode, animate); 87 88 // apply to lights out 89 applyLightsOut(mode == MODE_LIGHTS_OUT, animate, force); 90 } 91 92 private float alphaForMode(int mode) { 93 final boolean isOpaque = mode == MODE_OPAQUE || mode == MODE_LIGHTS_OUT; 94 return isOpaque ? KeyButtonView.DEFAULT_QUIESCENT_ALPHA : 1f; 95 } 96 97 public void applyBackButtonQuiescentAlpha(int mode, boolean animate) { 98 float backAlpha = 0; 99 backAlpha = maxVisibleQuiescentAlpha(backAlpha, mView.getSearchLight()); 100 backAlpha = maxVisibleQuiescentAlpha(backAlpha, mView.getHomeButton()); 101 backAlpha = maxVisibleQuiescentAlpha(backAlpha, mView.getRecentsButton()); 102 backAlpha = maxVisibleQuiescentAlpha(backAlpha, mView.getMenuButton()); 103 if (backAlpha > 0) { 104 setKeyButtonViewQuiescentAlpha(mView.getBackButton(), backAlpha, animate); 105 } 106 } 107 108 private static float maxVisibleQuiescentAlpha(float max, View v) { 109 if ((v instanceof KeyButtonView) && v.isShown()) { 110 return Math.max(max, ((KeyButtonView)v).getQuiescentAlpha()); 111 } 112 return max; 113 } 114 115 @Override 116 public void setContentVisible(boolean visible) { 117 final float alpha = visible ? 1 : 0; 118 fadeContent(mView.getBackButton(), alpha); 119 fadeContent(mView.getSearchLight(), alpha); 120 } 121 122 private void fadeContent(View v, float alpha) { 123 if (v != null) { 124 v.animate().alpha(alpha).setDuration(CONTENT_FADE_DURATION); 125 } 126 } 127 128 private void setKeyButtonViewQuiescentAlpha(View button, float alpha, boolean animate) { 129 if (button instanceof KeyButtonView) { 130 ((KeyButtonView) button).setQuiescentAlpha(alpha, animate); 131 } 132 } 133 134 private void applyLightsOut(boolean lightsOut, boolean animate, boolean force) { 135 if (!force && lightsOut == mLightsOut) return; 136 137 mLightsOut = lightsOut; 138 139 final View navButtons = mView.getCurrentView().findViewById(R.id.nav_buttons); 140 final View lowLights = mView.getCurrentView().findViewById(R.id.lights_out); 141 142 // ok, everyone, stop it right there 143 navButtons.animate().cancel(); 144 lowLights.animate().cancel(); 145 146 final float navButtonsAlpha = lightsOut ? 0f : 1f; 147 final float lowLightsAlpha = lightsOut ? 1f : 0f; 148 149 if (!animate) { 150 navButtons.setAlpha(navButtonsAlpha); 151 lowLights.setAlpha(lowLightsAlpha); 152 lowLights.setVisibility(lightsOut ? View.VISIBLE : View.GONE); 153 } else { 154 final int duration = lightsOut ? LIGHTS_OUT_DURATION : LIGHTS_IN_DURATION; 155 navButtons.animate() 156 .alpha(navButtonsAlpha) 157 .setDuration(duration) 158 .start(); 159 160 lowLights.setOnTouchListener(mLightsOutListener); 161 if (lowLights.getVisibility() == View.GONE) { 162 lowLights.setAlpha(0f); 163 lowLights.setVisibility(View.VISIBLE); 164 } 165 lowLights.animate() 166 .alpha(lowLightsAlpha) 167 .setDuration(duration) 168 .setInterpolator(new AccelerateInterpolator(2.0f)) 169 .setListener(lightsOut ? null : new AnimatorListenerAdapter() { 170 @Override 171 public void onAnimationEnd(Animator _a) { 172 lowLights.setVisibility(View.GONE); 173 } 174 }) 175 .start(); 176 } 177 } 178 179 private final View.OnTouchListener mLightsOutListener = new View.OnTouchListener() { 180 @Override 181 public boolean onTouch(View v, MotionEvent ev) { 182 if (ev.getAction() == MotionEvent.ACTION_DOWN) { 183 // even though setting the systemUI visibility below will turn these views 184 // on, we need them to come up faster so that they can catch this motion 185 // event 186 applyLightsOut(false, false, false); 187 188 try { 189 mBarService.setSystemUiVisibility(0, View.SYSTEM_UI_FLAG_LOW_PROFILE); 190 } catch (android.os.RemoteException ex) { 191 } 192 } 193 return false; 194 } 195 }; 196} 197