DO NOT MERGE Move clock and top padding while dismissing Keyguard.
Such translation. Much alpha. Very parallax. Wow. Bug: 15163546 Change-Id: Id419acced94083cf6cd7abebbcf1d5a08439b0a7 (cherry picked from commit c42bdc3ba9493efe68b9ed39fbd55c84ba175185)
This commit is contained in:
@@ -0,0 +1,186 @@
|
||||
/*
|
||||
* Copyright (C) 2014 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License
|
||||
*/
|
||||
|
||||
package com.android.systemui.statusbar.phone;
|
||||
|
||||
import android.content.res.Resources;
|
||||
import android.graphics.Path;
|
||||
import android.view.animation.PathInterpolator;
|
||||
|
||||
import com.android.systemui.R;
|
||||
|
||||
/**
|
||||
* Utility class to calculate the clock position and top padding of notifications on Keyguard.
|
||||
*/
|
||||
public class KeyguardClockPositionAlgorithm {
|
||||
|
||||
private static final float SLOW_DOWN_FACTOR = 0.4f;
|
||||
|
||||
private static final float CLOCK_RUBBERBAND_FACTOR_MIN = 0.08f;
|
||||
private static final float CLOCK_RUBBERBAND_FACTOR_MAX = 0.8f;
|
||||
|
||||
private static final float CLOCK_ADJ_TOP_PADDING_MULTIPLIER_MIN = 1.4f;
|
||||
private static final float CLOCK_ADJ_TOP_PADDING_MULTIPLIER_MAX = 3.2f;
|
||||
|
||||
private int mClockNotificationsMarginMin;
|
||||
private int mClockNotificationsMarginMax;
|
||||
private float mClockYFractionMin;
|
||||
private float mClockYFractionMax;
|
||||
private int mMaxKeyguardNotifications;
|
||||
private int mMaxPanelHeight;
|
||||
private float mExpandedHeight;
|
||||
private int mNotificationCount;
|
||||
private int mHeight;
|
||||
private int mKeyguardStatusHeight;
|
||||
|
||||
/**
|
||||
* The number (fractional) of notifications the "more" card counts when calculating how many
|
||||
* notifications are currently visible for the y positioning of the clock.
|
||||
*/
|
||||
private float mMoreCardNotificationAmount;
|
||||
|
||||
private static final PathInterpolator sSlowDownInterpolator;
|
||||
|
||||
static {
|
||||
Path path = new Path();
|
||||
path.moveTo(0, 0);
|
||||
path.cubicTo(0.3f, 0.875f, 0.6f, 1f, 1f, 1f);
|
||||
sSlowDownInterpolator = new PathInterpolator(path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Refreshes the dimension values.
|
||||
*/
|
||||
public void loadDimens(Resources res) {
|
||||
mClockNotificationsMarginMin = res.getDimensionPixelSize(
|
||||
R.dimen.keyguard_clock_notifications_margin_min);
|
||||
mClockNotificationsMarginMax = res.getDimensionPixelSize(
|
||||
R.dimen.keyguard_clock_notifications_margin_max);
|
||||
mClockYFractionMin = res.getFraction(R.fraction.keyguard_clock_y_fraction_min, 1, 1);
|
||||
mClockYFractionMax = res.getFraction(R.fraction.keyguard_clock_y_fraction_max, 1, 1);
|
||||
mMoreCardNotificationAmount =
|
||||
(float) res.getDimensionPixelSize(R.dimen.notification_summary_height) /
|
||||
res.getDimensionPixelSize(R.dimen.notification_min_height);
|
||||
}
|
||||
|
||||
public void setup(int maxKeyguardNotifications, int maxPanelHeight, float expandedHeight,
|
||||
int notificationCount, int height, int keyguardStatusHeight) {
|
||||
mMaxKeyguardNotifications = maxKeyguardNotifications;
|
||||
mMaxPanelHeight = maxPanelHeight;
|
||||
mExpandedHeight = expandedHeight;
|
||||
mNotificationCount = notificationCount;
|
||||
mHeight = height;
|
||||
mKeyguardStatusHeight = keyguardStatusHeight;
|
||||
}
|
||||
|
||||
public void run(Result result) {
|
||||
int y = getClockY() - mKeyguardStatusHeight/2;
|
||||
float clockAdjustment = getClockYExpansionAdjustment();
|
||||
float topPaddingAdjMultiplier = getTopPaddingAdjMultiplier();
|
||||
result.stackScrollerPaddingAdjustment = (int) (clockAdjustment*topPaddingAdjMultiplier);
|
||||
int clockNotificationsPadding = getClockNotificationsPadding()
|
||||
+ result.stackScrollerPaddingAdjustment;
|
||||
int padding = y + clockNotificationsPadding;
|
||||
y += clockAdjustment;
|
||||
result.clockY = y;
|
||||
result.stackScrollerPadding = mKeyguardStatusHeight + padding;
|
||||
result.clockAlpha = getClockAlpha(result.stackScrollerPadding
|
||||
- (y + mKeyguardStatusHeight));
|
||||
}
|
||||
|
||||
private int getClockNotificationsPadding() {
|
||||
float t = getNotificationAmountT();
|
||||
t = Math.min(t, 1.0f);
|
||||
return (int) (t * mClockNotificationsMarginMin + (1 - t) * mClockNotificationsMarginMax);
|
||||
}
|
||||
|
||||
private float getClockYFraction() {
|
||||
float t = getNotificationAmountT();
|
||||
t = Math.min(t, 1.0f);
|
||||
return (1 - t) * mClockYFractionMax + t * mClockYFractionMin;
|
||||
}
|
||||
|
||||
private int getClockY() {
|
||||
return (int) (getClockYFraction() * mHeight);
|
||||
}
|
||||
|
||||
private float getClockYExpansionAdjustment() {
|
||||
float rubberbandFactor = getClockYExpansionRubberbandFactor();
|
||||
float value = (rubberbandFactor * (mMaxPanelHeight - mExpandedHeight));
|
||||
float t = value / mMaxPanelHeight;
|
||||
float slowedDownValue = -sSlowDownInterpolator.getInterpolation(t) * SLOW_DOWN_FACTOR
|
||||
* mMaxPanelHeight;
|
||||
if (mNotificationCount == 0) {
|
||||
return (-2*value + slowedDownValue)/3;
|
||||
} else {
|
||||
return slowedDownValue;
|
||||
}
|
||||
}
|
||||
|
||||
private float getClockYExpansionRubberbandFactor() {
|
||||
float t = getNotificationAmountT();
|
||||
t = Math.min(t, 1.0f);
|
||||
t = (float) Math.pow(t, 0.3f);
|
||||
return (1 - t) * CLOCK_RUBBERBAND_FACTOR_MAX + t * CLOCK_RUBBERBAND_FACTOR_MIN;
|
||||
}
|
||||
|
||||
private float getTopPaddingAdjMultiplier() {
|
||||
float t = getNotificationAmountT();
|
||||
t = Math.min(t, 1.0f);
|
||||
return (1 - t) * CLOCK_ADJ_TOP_PADDING_MULTIPLIER_MIN
|
||||
+ t * CLOCK_ADJ_TOP_PADDING_MULTIPLIER_MAX;
|
||||
}
|
||||
|
||||
private float getClockAlpha(int clockNotificationPadding) {
|
||||
float t = getNotificationAmountT();
|
||||
t = (float) Math.pow(t, 0.3f);
|
||||
float multiplier = 1 + 2 * (1 - t);
|
||||
float alpha = 1 + (float) clockNotificationPadding * multiplier / mKeyguardStatusHeight * 3;
|
||||
return Math.max(0, Math.min(1, alpha));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return a value from 0 to 1 depending on how many notification there are
|
||||
*/
|
||||
private float getNotificationAmountT() {
|
||||
return mNotificationCount
|
||||
/ (mMaxKeyguardNotifications + mMoreCardNotificationAmount);
|
||||
}
|
||||
|
||||
public static class Result {
|
||||
|
||||
/**
|
||||
* The y translation of the clock.
|
||||
*/
|
||||
public int clockY;
|
||||
|
||||
/**
|
||||
* The alpha value of the clock.
|
||||
*/
|
||||
public float clockAlpha;
|
||||
|
||||
/**
|
||||
* The top padding of the stack scroller, in pixels.
|
||||
*/
|
||||
public int stackScrollerPadding;
|
||||
|
||||
/**
|
||||
* The top padding adjustment of the stack scroller, in pixels. This value is used to adjust
|
||||
* the padding, but not the overall panel size.
|
||||
*/
|
||||
public int stackScrollerPaddingAdjustment;
|
||||
}
|
||||
}
|
||||
@@ -19,10 +19,11 @@ package com.android.systemui.statusbar.phone;
|
||||
import android.animation.Animator;
|
||||
import android.animation.AnimatorListenerAdapter;
|
||||
import android.animation.ObjectAnimator;
|
||||
import android.animation.PropertyValuesHolder;
|
||||
import android.animation.ValueAnimator;
|
||||
import android.content.Context;
|
||||
import android.graphics.Path;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.Log;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.VelocityTracker;
|
||||
import android.view.View;
|
||||
@@ -31,6 +32,7 @@ import android.view.ViewTreeObserver;
|
||||
import android.view.accessibility.AccessibilityEvent;
|
||||
import android.view.animation.AnimationUtils;
|
||||
import android.view.animation.Interpolator;
|
||||
import android.view.animation.PathInterpolator;
|
||||
import android.widget.LinearLayout;
|
||||
|
||||
import com.android.systemui.R;
|
||||
@@ -82,19 +84,14 @@ public class NotificationPanelView extends PanelView implements
|
||||
private FlingAnimationUtils mFlingAnimationUtils;
|
||||
private int mStatusBarMinHeight;
|
||||
|
||||
private int mClockNotificationsMarginMin;
|
||||
private int mClockNotificationsMarginMax;
|
||||
private float mClockYFractionMin;
|
||||
private float mClockYFractionMax;
|
||||
private Interpolator mFastOutSlowInInterpolator;
|
||||
private ObjectAnimator mClockAnimator;
|
||||
private int mClockAnimationTarget = -1;
|
||||
|
||||
/**
|
||||
* The number (fractional) of notifications the "more" card counts when calculating how many
|
||||
* notifications are currently visible for the y positioning of the clock.
|
||||
*/
|
||||
private float mMoreCardNotificationAmount;
|
||||
private int mTopPaddingAdjustment;
|
||||
private KeyguardClockPositionAlgorithm mClockPositionAlgorithm =
|
||||
new KeyguardClockPositionAlgorithm();
|
||||
private KeyguardClockPositionAlgorithm.Result mClockPositionResult =
|
||||
new KeyguardClockPositionAlgorithm.Result();
|
||||
|
||||
public NotificationPanelView(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
@@ -139,20 +136,10 @@ public class NotificationPanelView extends PanelView implements
|
||||
mNotificationTopPadding = getResources().getDimensionPixelSize(
|
||||
R.dimen.notifications_top_padding);
|
||||
mMinStackHeight = getResources().getDimensionPixelSize(R.dimen.collapsed_stack_height);
|
||||
mClockNotificationsMarginMin = getResources().getDimensionPixelSize(
|
||||
R.dimen.keyguard_clock_notifications_margin_min);
|
||||
mClockNotificationsMarginMax = getResources().getDimensionPixelSize(
|
||||
R.dimen.keyguard_clock_notifications_margin_max);
|
||||
mClockYFractionMin =
|
||||
getResources().getFraction(R.fraction.keyguard_clock_y_fraction_min, 1, 1);
|
||||
mClockYFractionMax =
|
||||
getResources().getFraction(R.fraction.keyguard_clock_y_fraction_max, 1, 1);
|
||||
mMoreCardNotificationAmount =
|
||||
(float) getResources().getDimensionPixelSize(R.dimen.notification_summary_height) /
|
||||
getResources().getDimensionPixelSize(R.dimen.notification_min_height);
|
||||
mFlingAnimationUtils = new FlingAnimationUtils(getContext(), 0.4f);
|
||||
mStatusBarMinHeight = getResources().getDimensionPixelSize(
|
||||
com.android.internal.R.dimen.status_bar_height);
|
||||
mClockPositionAlgorithm.loadDimens(getResources());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -160,6 +147,7 @@ public class NotificationPanelView extends PanelView implements
|
||||
super.onLayout(changed, left, top, right, bottom);
|
||||
if (!mQsExpanded) {
|
||||
positionClockAndNotifications();
|
||||
mNotificationStackScroller.setStackHeight(getExpandedHeight());
|
||||
}
|
||||
|
||||
// Calculate quick setting heights.
|
||||
@@ -178,16 +166,24 @@ public class NotificationPanelView extends PanelView implements
|
||||
boolean animateClock = mNotificationStackScroller.isAddOrRemoveAnimationPending();
|
||||
if (mStatusBar.getBarState() != StatusBarState.KEYGUARD) {
|
||||
mStackScrollerIntrinsicPadding = mHeader.getBottom() + mNotificationTopPadding;
|
||||
mTopPaddingAdjustment = 0;
|
||||
} else {
|
||||
int notificationCount = mNotificationStackScroller.getNotGoneChildCount();
|
||||
int y = getClockY(notificationCount) - mKeyguardStatusView.getHeight()/2;
|
||||
int padding = getClockNotificationsPadding(notificationCount);
|
||||
mClockPositionAlgorithm.setup(
|
||||
mStatusBar.getMaxKeyguardNotifications(),
|
||||
getMaxPanelHeight(),
|
||||
getExpandedHeight(),
|
||||
mNotificationStackScroller.getNotGoneChildCount(),
|
||||
getHeight(),
|
||||
mKeyguardStatusView.getHeight());
|
||||
mClockPositionAlgorithm.run(mClockPositionResult);
|
||||
if (animateClock || mClockAnimator != null) {
|
||||
startClockAnimation(y);
|
||||
startClockAnimation(mClockPositionResult.clockY);
|
||||
} else {
|
||||
mKeyguardStatusView.setY(y);
|
||||
mKeyguardStatusView.setY(mClockPositionResult.clockY);
|
||||
}
|
||||
mStackScrollerIntrinsicPadding = y + mKeyguardStatusView.getHeight() + padding;
|
||||
applyClockAlpha(mClockPositionResult.clockAlpha);
|
||||
mStackScrollerIntrinsicPadding = mClockPositionResult.stackScrollerPadding;
|
||||
mTopPaddingAdjustment = mClockPositionResult.stackScrollerPaddingAdjustment;
|
||||
}
|
||||
mNotificationStackScroller.setTopPadding(mStackScrollerIntrinsicPadding,
|
||||
mAnimateNextTopPaddingChange || animateClock);
|
||||
@@ -224,22 +220,13 @@ public class NotificationPanelView extends PanelView implements
|
||||
});
|
||||
}
|
||||
|
||||
private int getClockNotificationsPadding(int notificationCount) {
|
||||
float t = notificationCount
|
||||
/ (mStatusBar.getMaxKeyguardNotifications() + mMoreCardNotificationAmount);
|
||||
t = Math.min(t, 1.0f);
|
||||
return (int) (t * mClockNotificationsMarginMin + (1 - t) * mClockNotificationsMarginMax);
|
||||
}
|
||||
|
||||
private float getClockYFraction(int notificationCount) {
|
||||
float t = notificationCount
|
||||
/ (mStatusBar.getMaxKeyguardNotifications() + mMoreCardNotificationAmount);
|
||||
t = Math.min(t, 1.0f);
|
||||
return (1 - t) * mClockYFractionMax + t * mClockYFractionMin;
|
||||
}
|
||||
|
||||
private int getClockY(int notificationCount) {
|
||||
return (int) (getClockYFraction(notificationCount) * getHeight());
|
||||
private void applyClockAlpha(float alpha) {
|
||||
if (alpha != 1.0f) {
|
||||
mKeyguardStatusView.setLayerType(LAYER_TYPE_HARDWARE, null);
|
||||
} else {
|
||||
mKeyguardStatusView.setLayerType(LAYER_TYPE_NONE, null);
|
||||
}
|
||||
mKeyguardStatusView.setAlpha(alpha);
|
||||
}
|
||||
|
||||
public void animateToFullShade() {
|
||||
@@ -626,7 +613,7 @@ public class NotificationPanelView extends PanelView implements
|
||||
int emptyBottomMargin = mStackScrollerContainer.getHeight()
|
||||
- mNotificationStackScroller.getHeight()
|
||||
+ mNotificationStackScroller.getEmptyBottomMargin();
|
||||
int maxHeight = maxPanelHeight - emptyBottomMargin;
|
||||
int maxHeight = maxPanelHeight - emptyBottomMargin - mTopPaddingAdjustment;
|
||||
maxHeight = Math.max(maxHeight, mStatusBarMinHeight);
|
||||
return maxHeight;
|
||||
}
|
||||
@@ -637,6 +624,9 @@ public class NotificationPanelView extends PanelView implements
|
||||
|
||||
@Override
|
||||
protected void onHeightUpdated(float expandedHeight) {
|
||||
if (!mQsExpanded) {
|
||||
positionClockAndNotifications();
|
||||
}
|
||||
mNotificationStackScroller.setStackHeight(expandedHeight);
|
||||
}
|
||||
|
||||
|
||||
@@ -402,7 +402,7 @@ public class PanelView extends FrameLayout {
|
||||
|
||||
public void setExpandedHeightInternal(float h) {
|
||||
float fh = getMaxPanelHeight();
|
||||
mExpandedHeight = h;
|
||||
mExpandedHeight = Math.min(fh, h);
|
||||
|
||||
if (DEBUG) {
|
||||
logf("setExpansion: height=%.1f fh=%.1f tracking=%s", h, fh, mTracking ? "T" : "f");
|
||||
|
||||
Reference in New Issue
Block a user