summaryrefslogtreecommitdiffstats
path: root/packages
diff options
context:
space:
mode:
authorJorim Jaggi <jjaggi@google.com>2014-08-07 17:45:04 +0200
committerJorim Jaggi <jjaggi@google.com>2014-08-07 21:57:34 +0000
commit98f8530af3bb8636b7b173443c90686c485205d6 (patch)
tree8eb88497bb4113936531e7dcf770eae79ce0679b /packages
parent546c635ad9a26421fbdf54efa765b5ab0a63c191 (diff)
downloadframeworks_base-98f8530af3bb8636b7b173443c90686c485205d6.zip
frameworks_base-98f8530af3bb8636b7b173443c90686c485205d6.tar.gz
frameworks_base-98f8530af3bb8636b7b173443c90686c485205d6.tar.bz2
Animations for Keyguard user switcher.
Bug: 15757197 Change-Id: Ia3fcc0f771cea37fc2d57181d859373c423954a7
Diffstat (limited to 'packages')
-rw-r--r--packages/Keyguard/src/com/android/keyguard/AppearAnimationUtils.java73
-rw-r--r--packages/Keyguard/src/com/android/keyguard/KeyguardPatternView.java9
-rw-r--r--packages/SystemUI/res/layout/keyguard_user_switcher.xml5
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/tiles/UserDetailItemView.java5
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarView.java77
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/MultiUserSwitch.java7
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java15
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardUserSwitcher.java99
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardUserSwitcherScrim.java38
10 files changed, 281 insertions, 49 deletions
diff --git a/packages/Keyguard/src/com/android/keyguard/AppearAnimationUtils.java b/packages/Keyguard/src/com/android/keyguard/AppearAnimationUtils.java
index 6bb1f2c..e664fb9 100644
--- a/packages/Keyguard/src/com/android/keyguard/AppearAnimationUtils.java
+++ b/packages/Keyguard/src/com/android/keyguard/AppearAnimationUtils.java
@@ -26,38 +26,70 @@ import android.view.animation.Interpolator;
*/
public class AppearAnimationUtils implements AppearAnimationCreator<View> {
- public static final long APPEAR_DURATION = 220;
+ public static final long DEFAULT_APPEAR_DURATION = 220;
- private final Interpolator mLinearOutSlowIn;
+ private final Interpolator mInterpolator;
private final float mStartTranslation;
private final AppearAnimationProperties mProperties = new AppearAnimationProperties();
private final float mDelayScale;
+ private final long mDuration;
public AppearAnimationUtils(Context ctx) {
- this(ctx, 1.0f, 1.0f);
+ this(ctx, DEFAULT_APPEAR_DURATION,
+ ctx.getResources().getDimensionPixelSize(R.dimen.appear_y_translation_start),
+ 1.0f,
+ AnimationUtils.loadInterpolator(ctx, android.R.interpolator.linear_out_slow_in));
}
- public AppearAnimationUtils(Context ctx, float delayScaleFactor,
- float translationScaleFactor) {
- mLinearOutSlowIn = AnimationUtils.loadInterpolator(
- ctx, android.R.interpolator.linear_out_slow_in);
+ public AppearAnimationUtils(Context ctx, long duration, float translationScaleFactor,
+ float delayScaleFactor, Interpolator interpolator) {
+ mInterpolator = interpolator;
mStartTranslation = ctx.getResources().getDimensionPixelOffset(
R.dimen.appear_y_translation_start) * translationScaleFactor;
mDelayScale = delayScaleFactor;
+ mDuration = duration;
}
public void startAppearAnimation(View[][] objects, final Runnable finishListener) {
startAppearAnimation(objects, finishListener, this);
}
+ public void startAppearAnimation(View[] objects, final Runnable finishListener) {
+ startAppearAnimation(objects, finishListener, this);
+ }
+
public <T> void startAppearAnimation(T[][] objects, final Runnable finishListener,
AppearAnimationCreator<T> creator) {
AppearAnimationProperties properties = getDelays(objects);
startAnimations(properties, objects, finishListener, creator);
}
+ public <T> void startAppearAnimation(T[] objects, final Runnable finishListener,
+ AppearAnimationCreator<T> creator) {
+ AppearAnimationProperties properties = getDelays(objects);
+ startAnimations(properties, objects, finishListener, creator);
+ }
+
+ private <T> void startAnimations(AppearAnimationProperties properties, T[] objects,
+ final Runnable finishListener, AppearAnimationCreator<T> creator) {
+ if (properties.maxDelayRowIndex == -1 || properties.maxDelayColIndex == -1) {
+ finishListener.run();
+ return;
+ }
+ for (int row = 0; row < properties.delays.length; row++) {
+ long[] columns = properties.delays[row];
+ long delay = columns[0];
+ Runnable endRunnable = null;
+ if (properties.maxDelayRowIndex == row && properties.maxDelayColIndex == 0) {
+ endRunnable = finishListener;
+ }
+ creator.createAnimation(objects[row], delay, mDuration,
+ mStartTranslation, mInterpolator, endRunnable);
+ }
+ }
+
private <T> void startAnimations(AppearAnimationProperties properties, T[][] objects,
- final Runnable finishListener, AppearAnimationCreator creator) {;
+ final Runnable finishListener, AppearAnimationCreator<T> creator) {
if (properties.maxDelayRowIndex == -1 || properties.maxDelayColIndex == -1) {
finishListener.run();
return;
@@ -70,15 +102,32 @@ public class AppearAnimationUtils implements AppearAnimationCreator<View> {
if (properties.maxDelayRowIndex == row && properties.maxDelayColIndex == col) {
endRunnable = finishListener;
}
- creator.createAnimation(objects[row][col], delay, APPEAR_DURATION,
- mStartTranslation, mLinearOutSlowIn, endRunnable);
+ creator.createAnimation(objects[row][col], delay, mDuration,
+ mStartTranslation, mInterpolator, endRunnable);
}
}
+ }
+ private <T> AppearAnimationProperties getDelays(T[] items) {
+ long maxDelay = -1;
+ mProperties.maxDelayColIndex = -1;
+ mProperties.maxDelayRowIndex = -1;
+ mProperties.delays = new long[items.length][];
+ for (int row = 0; row < items.length; row++) {
+ mProperties.delays[row] = new long[1];
+ long delay = calculateDelay(row, 0);
+ mProperties.delays[row][0] = delay;
+ if (items[row] != null && delay > maxDelay) {
+ maxDelay = delay;
+ mProperties.maxDelayColIndex = 0;
+ mProperties.maxDelayRowIndex = row;
+ }
+ }
+ return mProperties;
}
private <T> AppearAnimationProperties getDelays(T[][] items) {
- long maxDelay = 0;
+ long maxDelay = -1;
mProperties.maxDelayColIndex = -1;
mProperties.maxDelayRowIndex = -1;
mProperties.delays = new long[items.length][];
@@ -103,7 +152,7 @@ public class AppearAnimationUtils implements AppearAnimationCreator<View> {
}
public Interpolator getInterpolator() {
- return mLinearOutSlowIn;
+ return mInterpolator;
}
public float getStartTranslation() {
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardPatternView.java b/packages/Keyguard/src/com/android/keyguard/KeyguardPatternView.java
index d5dcd71..12bbd35 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardPatternView.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardPatternView.java
@@ -37,6 +37,7 @@ import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
+import android.view.animation.AnimationUtils;
import android.view.animation.Interpolator;
import android.widget.Button;
import android.widget.LinearLayout;
@@ -108,8 +109,10 @@ public class KeyguardPatternView extends LinearLayout implements KeyguardSecurit
public KeyguardPatternView(Context context, AttributeSet attrs) {
super(context, attrs);
mKeyguardUpdateMonitor = KeyguardUpdateMonitor.getInstance(mContext);
- mAppearAnimationUtils = new AppearAnimationUtils(context, 1.5f /* delayScale */,
- 2.0f /* transitionScale */);
+ mAppearAnimationUtils = new AppearAnimationUtils(context,
+ AppearAnimationUtils.DEFAULT_APPEAR_DURATION, 1.5f /* delayScale */,
+ 2.0f /* transitionScale */, AnimationUtils.loadInterpolator(
+ mContext, android.R.interpolator.linear_out_slow_in));
}
public void setKeyguardCallback(KeyguardSecurityCallback callback) {
@@ -420,7 +423,7 @@ public class KeyguardPatternView extends LinearLayout implements KeyguardSecurit
this);
if (!TextUtils.isEmpty(mHelpMessage.getText())) {
mAppearAnimationUtils.createAnimation(mHelpMessage, 0,
- AppearAnimationUtils.APPEAR_DURATION,
+ AppearAnimationUtils.DEFAULT_APPEAR_DURATION,
mAppearAnimationUtils.getStartTranslation(),
mAppearAnimationUtils.getInterpolator(),
null /* finishRunnable */);
diff --git a/packages/SystemUI/res/layout/keyguard_user_switcher.xml b/packages/SystemUI/res/layout/keyguard_user_switcher.xml
index 5648065..7c918c2 100644
--- a/packages/SystemUI/res/layout/keyguard_user_switcher.xml
+++ b/packages/SystemUI/res/layout/keyguard_user_switcher.xml
@@ -14,7 +14,8 @@
~ See the License for the specific language governing permissions and
~ limitations under the License
-->
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+<com.android.systemui.statusbar.AlphaOptimizedLinearLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/keyguard_user_switcher"
android:orientation="vertical"
android:layout_height="wrap_content"
@@ -22,4 +23,4 @@
android:gravity="end"
android:visibility="gone"
android:paddingTop="4dp">
-</LinearLayout>
+</com.android.systemui.statusbar.AlphaOptimizedLinearLayout>
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/UserDetailItemView.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/UserDetailItemView.java
index 759d540..a56b7a7 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/UserDetailItemView.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/UserDetailItemView.java
@@ -116,4 +116,9 @@ public class UserDetailItemView extends LinearLayout {
boolean activated = ArrayUtils.contains(getDrawableState(), android.R.attr.state_activated);
mName.setTypeface(activated ? mActivatedTypeface : mRegularTypeface);
}
+
+ @Override
+ public boolean hasOverlappingRendering() {
+ return false;
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarView.java
index bf66c41..b66c310 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarView.java
@@ -16,10 +16,14 @@
package com.android.systemui.statusbar.phone;
+import android.animation.LayoutTransition;
import android.content.Context;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.view.View;
+import android.view.ViewTreeObserver;
+import android.view.animation.AnimationUtils;
+import android.view.animation.Interpolator;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView;
@@ -48,6 +52,7 @@ public class KeyguardStatusBarView extends RelativeLayout
private KeyguardUserSwitcher mKeyguardUserSwitcher;
private int mSystemIconsSwitcherHiddenExpandedMargin;
+ private Interpolator mFastOutSlowInInterpolator;
public KeyguardStatusBarView(Context context, AttributeSet attrs) {
super(context, attrs);
@@ -61,6 +66,8 @@ public class KeyguardStatusBarView extends RelativeLayout
mMultiUserAvatar = (ImageView) findViewById(R.id.multi_user_avatar);
mBatteryLevel = (TextView) findViewById(R.id.battery_level);
loadDimens();
+ mFastOutSlowInInterpolator = AnimationUtils.loadInterpolator(getContext(),
+ android.R.interpolator.fast_out_slow_in);
updateUserSwitcher();
}
@@ -70,7 +77,14 @@ public class KeyguardStatusBarView extends RelativeLayout
}
private void updateVisibilities() {
- mMultiUserSwitch.setVisibility(!mKeyguardUserSwitcherShowing ? VISIBLE : GONE);
+ if (mMultiUserSwitch.getParent() != this && !mKeyguardUserSwitcherShowing) {
+ if (mMultiUserSwitch.getParent() != null) {
+ getOverlay().remove(mMultiUserSwitch);
+ }
+ addView(mMultiUserSwitch, 0);
+ } else if (mMultiUserSwitch.getParent() == this && mKeyguardUserSwitcherShowing) {
+ removeView(mMultiUserSwitch);
+ }
mBatteryLevel.setVisibility(mBatteryCharging ? View.VISIBLE : View.GONE);
}
@@ -137,12 +151,71 @@ public class KeyguardStatusBarView extends RelativeLayout
updateUserSwitcher();
}
- public void setKeyguardUserSwitcherShowing(boolean showing) {
+ public void setKeyguardUserSwitcherShowing(boolean showing, boolean animate) {
mKeyguardUserSwitcherShowing = showing;
+ if (animate) {
+ animateNextLayoutChange();
+ }
updateVisibilities();
updateSystemIconsLayoutParams();
}
+ private void animateNextLayoutChange() {
+ final int systemIconsCurrentX = mSystemIconsSuperContainer.getLeft();
+ final boolean userSwitcherVisible = mMultiUserSwitch.getParent() == this;
+ getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
+ @Override
+ public boolean onPreDraw() {
+ getViewTreeObserver().removeOnPreDrawListener(this);
+ boolean userSwitcherHiding = userSwitcherVisible
+ && mMultiUserSwitch.getParent() != KeyguardStatusBarView.this;
+ mSystemIconsSuperContainer.setX(systemIconsCurrentX);
+ mSystemIconsSuperContainer.animate()
+ .translationX(0)
+ .setDuration(400)
+ .setStartDelay(userSwitcherHiding ? 300 : 0)
+ .setInterpolator(mFastOutSlowInInterpolator)
+ .start();
+ if (userSwitcherHiding) {
+ getOverlay().add(mMultiUserSwitch);
+ mMultiUserSwitch.animate()
+ .alpha(0f)
+ .setDuration(300)
+ .setStartDelay(0)
+ .setInterpolator(PhoneStatusBar.ALPHA_OUT)
+ .withEndAction(new Runnable() {
+ @Override
+ public void run() {
+ mMultiUserSwitch.setAlpha(1f);
+ getOverlay().remove(mMultiUserSwitch);
+ }
+ })
+ .start();
+
+ } else {
+ mMultiUserSwitch.setAlpha(0f);
+ mMultiUserSwitch.animate()
+ .alpha(1f)
+ .setDuration(300)
+ .setStartDelay(200)
+ .setInterpolator(PhoneStatusBar.ALPHA_IN);
+ }
+ return true;
+ }
+ });
+
+ }
+
+ @Override
+ public void setVisibility(int visibility) {
+ super.setVisibility(visibility);
+ if (visibility != View.VISIBLE) {
+ mSystemIconsSuperContainer.animate().cancel();
+ mMultiUserSwitch.animate().cancel();
+ mMultiUserSwitch.setAlpha(1f);
+ }
+ }
+
@Override
public boolean hasOverlappingRendering() {
return false;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/MultiUserSwitch.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/MultiUserSwitch.java
index af30266..47325c8 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/MultiUserSwitch.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/MultiUserSwitch.java
@@ -65,7 +65,7 @@ public class MultiUserSwitch extends FrameLayout implements View.OnClickListener
if (um.isUserSwitcherEnabled()) {
if (mKeyguardMode) {
if (mKeyguardUserSwitcher != null) {
- mKeyguardUserSwitcher.show();
+ mKeyguardUserSwitcher.show(true /* animate */);
}
} else {
mQsPanel.showDetailAdapter(true,
@@ -78,4 +78,9 @@ public class MultiUserSwitch extends FrameLayout implements View.OnClickListener
getContext().startActivityAsUser(intent, new UserHandle(UserHandle.USER_CURRENT));
}
}
+
+ @Override
+ public boolean hasOverlappingRendering() {
+ return false;
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
index e70422b..74ae4a4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
@@ -950,7 +950,7 @@ public class NotificationPanelView extends PanelView implements
? View.VISIBLE
: View.INVISIBLE);
if (mKeyguardUserSwitcher != null && mQsExpanded && !mStackScrollerOverscrolling) {
- mKeyguardUserSwitcher.hide();
+ mKeyguardUserSwitcher.hide(true /* animate */);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
index 1d678af..75e31e4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -3341,7 +3341,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
public void showKeyguard() {
setBarState(StatusBarState.KEYGUARD);
- updateKeyguardState(false /* goingToFullShade */);
+ updateKeyguardState(false /* goingToFullShade */, false /* fromShadeLocked */);
instantExpandNotificationsPanel();
mLeaveOpenOnKeyguardHide = false;
if (mDraggedDownRow != null) {
@@ -3413,7 +3413,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
} else {
instantCollapseNotificationPanel();
}
- updateKeyguardState(staying);
+ updateKeyguardState(staying, false /* fromShadeLocked */);
return staying;
}
@@ -3449,14 +3449,15 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
&& mStatusBarKeyguardViewManager.isSecure());
}
- private void updateKeyguardState(boolean goingToFullShade) {
+ private void updateKeyguardState(boolean goingToFullShade, boolean fromShadeLocked) {
if (mState == StatusBarState.KEYGUARD) {
mKeyguardIndicationController.setVisible(true);
mNotificationPanel.resetViews();
- mKeyguardUserSwitcher.setKeyguard(true);
+ mKeyguardUserSwitcher.setKeyguard(true, fromShadeLocked);
} else {
mKeyguardIndicationController.setVisible(false);
- mKeyguardUserSwitcher.setKeyguard(false);
+ mKeyguardUserSwitcher.setKeyguard(false,
+ goingToFullShade || mState == StatusBarState.SHADE_LOCKED || fromShadeLocked);
}
if (mState == StatusBarState.KEYGUARD || mState == StatusBarState.SHADE_LOCKED) {
mScrimController.setKeyguardShowing(true);
@@ -3686,7 +3687,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
} else {
mNotificationPanel.animateToFullShade(0 /* delay */);
setBarState(StatusBarState.SHADE_LOCKED);
- updateKeyguardState(false /* goingToFullShade */);
+ updateKeyguardState(false /* goingToFullShade */, false /* fromShadeLocked */);
if (row != null) {
row.setUserLocked(false);
}
@@ -3699,7 +3700,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
public void goToKeyguard() {
if (mState == StatusBarState.SHADE_LOCKED) {
setBarState(StatusBarState.KEYGUARD);
- updateKeyguardState(false /* goingToFullShade */);
+ updateKeyguardState(false /* goingToFullShade */, true /* fromShadeLocked*/);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardUserSwitcher.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardUserSwitcher.java
index 203196e..18583ee 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardUserSwitcher.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardUserSwitcher.java
@@ -16,18 +16,25 @@
package com.android.systemui.statusbar.policy;
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.ObjectAnimator;
+import android.animation.ValueAnimator;
import android.content.Context;
import android.database.DataSetObserver;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewStub;
+import android.view.animation.AnimationUtils;
import android.widget.TextView;
+import com.android.keyguard.AppearAnimationUtils;
import com.android.systemui.R;
import com.android.systemui.qs.tiles.UserDetailItemView;
import com.android.systemui.statusbar.phone.KeyguardStatusBarView;
import com.android.systemui.statusbar.phone.NotificationPanelView;
+import com.android.systemui.statusbar.phone.PhoneStatusBar;
import com.android.systemui.statusbar.phone.StatusBarHeaderView;
import com.android.systemui.statusbar.phone.UserAvatarView;
@@ -43,33 +50,42 @@ public class KeyguardUserSwitcher {
private final KeyguardStatusBarView mStatusBarView;
private final Adapter mAdapter;
private final boolean mSimpleUserSwitcher;
+ private final AppearAnimationUtils mAppearAnimationUtils;
+ private final KeyguardUserSwitcherScrim mBackground;
+ private ObjectAnimator mBgAnimator;
public KeyguardUserSwitcher(Context context, ViewStub userSwitcher,
KeyguardStatusBarView statusBarView, NotificationPanelView panelView,
UserSwitcherController userSwitcherController) {
if (context.getResources().getBoolean(R.bool.config_keyguardUserSwitcher) || ALWAYS_ON) {
mUserSwitcher = (ViewGroup) userSwitcher.inflate();
- mUserSwitcher.setBackground(new KeyguardUserSwitcherScrim(mUserSwitcher));
+ mBackground = new KeyguardUserSwitcherScrim(mUserSwitcher);
+ mUserSwitcher.setBackground(mBackground);
mStatusBarView = statusBarView;
mStatusBarView.setKeyguardUserSwitcher(this);
panelView.setKeyguardUserSwitcher(this);
mAdapter = new Adapter(context, userSwitcherController);
mAdapter.registerDataSetObserver(mDataSetObserver);
mSimpleUserSwitcher = userSwitcherController.isSimpleUserSwitcher();
+ mAppearAnimationUtils = new AppearAnimationUtils(context, 400, -0.5f, 0.5f,
+ AnimationUtils.loadInterpolator(
+ context, android.R.interpolator.fast_out_slow_in));
} else {
mUserSwitcher = null;
mStatusBarView = null;
mAdapter = null;
mSimpleUserSwitcher = false;
+ mAppearAnimationUtils = null;
+ mBackground = null;
}
}
- public void setKeyguard(boolean keyguard) {
+ public void setKeyguard(boolean keyguard, boolean animate) {
if (mUserSwitcher != null) {
if (keyguard && shouldExpandByDefault()) {
- show();
+ show(animate);
} else {
- hide();
+ hide(animate);
}
}
}
@@ -82,20 +98,79 @@ public class KeyguardUserSwitcher {
return mSimpleUserSwitcher;
}
- public void show() {
- if (mUserSwitcher != null) {
- // TODO: animate
+ public void show(boolean animate) {
+ if (mUserSwitcher != null && mUserSwitcher.getVisibility() != View.VISIBLE) {
+ cancelAnimations();
mUserSwitcher.setVisibility(View.VISIBLE);
- mStatusBarView.setKeyguardUserSwitcherShowing(true);
+ mStatusBarView.setKeyguardUserSwitcherShowing(true, animate);
+ if (animate) {
+ startAppearAnimation();
+ }
}
}
- public void hide() {
+ public void hide(boolean animate) {
if (mUserSwitcher != null && mUserSwitcher.getVisibility() == View.VISIBLE) {
- // TODO: animate
- mUserSwitcher.setVisibility(View.GONE);
- mStatusBarView.setKeyguardUserSwitcherShowing(false);
+ cancelAnimations();
+ if (animate) {
+ startDisappearAnimation();
+ } else {
+ mUserSwitcher.setVisibility(View.GONE);
+ }
+ mStatusBarView.setKeyguardUserSwitcherShowing(false, animate);
+ }
+ }
+
+ private void cancelAnimations() {
+ int count = mUserSwitcher.getChildCount();
+ for (int i = 0; i < count; i++) {
+ mUserSwitcher.getChildAt(i).animate().cancel();
+ }
+ if (mBgAnimator != null) {
+ mBgAnimator.cancel();
}
+ mUserSwitcher.animate().cancel();
+ }
+
+ private void startAppearAnimation() {
+ int count = mUserSwitcher.getChildCount();
+ View[] objects = new View[count];
+ for (int i = 0; i < count; i++) {
+ objects[i] = mUserSwitcher.getChildAt(i);
+ }
+ mUserSwitcher.setClipChildren(false);
+ mUserSwitcher.setClipToPadding(false);
+ mAppearAnimationUtils.startAppearAnimation(objects, new Runnable() {
+ @Override
+ public void run() {
+ mUserSwitcher.setClipChildren(true);
+ mUserSwitcher.setClipToPadding(true);
+ }
+ });
+ mBgAnimator = ObjectAnimator.ofInt(mBackground, "alpha", 0, 255);
+ mBgAnimator.setDuration(400);
+ mBgAnimator.setInterpolator(PhoneStatusBar.ALPHA_IN);
+ mBgAnimator.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ mBgAnimator = null;
+ }
+ });
+ mBgAnimator.start();
+ }
+
+ private void startDisappearAnimation() {
+ mUserSwitcher.animate()
+ .alpha(0f)
+ .setDuration(300)
+ .setInterpolator(PhoneStatusBar.ALPHA_OUT)
+ .withEndAction(new Runnable() {
+ @Override
+ public void run() {
+ mUserSwitcher.setVisibility(View.GONE);
+ mUserSwitcher.setAlpha(1f);
+ }
+ });
}
private void refresh() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardUserSwitcherScrim.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardUserSwitcherScrim.java
index 3356afd..4363037 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardUserSwitcherScrim.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardUserSwitcherScrim.java
@@ -19,6 +19,7 @@ package com.android.systemui.statusbar.policy;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.ColorFilter;
+import android.graphics.LightingColorFilter;
import android.graphics.Paint;
import android.graphics.PixelFormat;
import android.graphics.RadialGradient;
@@ -41,7 +42,9 @@ public class KeyguardUserSwitcherScrim extends Drawable
private int mDarkColor;
private int mTop;
+ private int mAlpha;
private Paint mRadialGradientPaint = new Paint();
+ private int mLayoutWidth;
public KeyguardUserSwitcherScrim(View host) {
host.addOnLayoutChangeListener(this);
@@ -56,13 +59,21 @@ public class KeyguardUserSwitcherScrim extends Drawable
float width = bounds.width() * OUTER_EXTENT;
float height = (mTop + bounds.height()) * OUTER_EXTENT;
canvas.translate(0, -mTop);
- canvas.scale(1, height/width);
+ canvas.scale(1, height / width);
canvas.drawRect(isLtr ? bounds.right - width : 0, 0,
isLtr ? bounds.right : bounds.left + width, width, mRadialGradientPaint);
}
@Override
public void setAlpha(int alpha) {
+ mAlpha = alpha;
+ updatePaint();
+ invalidateSelf();
+ }
+
+ @Override
+ public int getAlpha() {
+ return mAlpha;
}
@Override
@@ -78,15 +89,24 @@ public class KeyguardUserSwitcherScrim extends Drawable
public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft,
int oldTop, int oldRight, int oldBottom) {
if (left != oldLeft || top != oldTop || right != oldRight || bottom != oldBottom) {
- int width = right - left;
- float radius = width * OUTER_EXTENT;
- boolean isLtr = getLayoutDirection() == LayoutDirection.LTR;
- mRadialGradientPaint.setShader(
- new RadialGradient(isLtr ? width : 0, 0, radius,
- new int[] { mDarkColor, Color.TRANSPARENT},
- new float[] { Math.max(0f, width * INNER_EXTENT / radius), 1f},
- Shader.TileMode.CLAMP));
+ mLayoutWidth = right - left;
mTop = top;
+ updatePaint();
}
}
+
+ private void updatePaint() {
+ if (mLayoutWidth == 0) {
+ return;
+ }
+ float radius = mLayoutWidth * OUTER_EXTENT;
+ boolean isLtr = getLayoutDirection() == LayoutDirection.LTR;
+ mRadialGradientPaint.setShader(
+ new RadialGradient(isLtr ? mLayoutWidth : 0, 0, radius,
+ new int[] { Color.argb(
+ (int) (Color.alpha(mDarkColor) * mAlpha / 255f), 0, 0, 0),
+ Color.TRANSPARENT },
+ new float[] { Math.max(0f, mLayoutWidth * INNER_EXTENT / radius), 1f },
+ Shader.TileMode.CLAMP));
+ }
}