Improve motion when expanding/collapsing status bar.
- Don't fade the whole panel anymore. - Parallax effect for QS header translation, fade on keyguard. - Improve fling curve for dismissing the panel. - Improve peeking behavior. Bug: 14804452 Bug: 15407838 Change-Id: I34b7bcd457cb8a037e0bb06e9802ec66d2b39b73
This commit is contained in:
@@ -48,28 +48,36 @@
|
||||
android:orientation="horizontal"
|
||||
>
|
||||
|
||||
<LinearLayout
|
||||
<com.android.systemui.statusbar.AlphaOptimizedLinearLayout
|
||||
android:id="@+id/notification_icon_area"
|
||||
android:layout_width="0dip"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_weight="1"
|
||||
android:orientation="horizontal"
|
||||
>
|
||||
<com.android.systemui.statusbar.StatusBarIconView android:id="@+id/moreIcon"
|
||||
android:layout_width="@dimen/status_bar_icon_size"
|
||||
android:layout_height="match_parent"
|
||||
android:src="@drawable/stat_notify_more"
|
||||
android:visibility="gone"
|
||||
/>
|
||||
<com.android.systemui.statusbar.phone.IconMerger android:id="@+id/notificationIcons"
|
||||
<!-- The alpha of this area is both controlled from PhoneStatusBarTransitions and
|
||||
PhoneStatusBar (DISABLE_NOTIFICATION_ICONS), so we need two views here. -->
|
||||
<com.android.systemui.statusbar.AlphaOptimizedFrameLayout
|
||||
android:id="@+id/notification_icon_area_inner"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_alignParentStart="true"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal"/>
|
||||
</LinearLayout>
|
||||
>
|
||||
<com.android.systemui.statusbar.StatusBarIconView android:id="@+id/moreIcon"
|
||||
android:layout_width="@dimen/status_bar_icon_size"
|
||||
android:layout_height="match_parent"
|
||||
android:src="@drawable/stat_notify_more"
|
||||
android:visibility="gone"
|
||||
/>
|
||||
<com.android.systemui.statusbar.phone.IconMerger android:id="@+id/notificationIcons"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_alignParentStart="true"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal"/>
|
||||
</com.android.systemui.statusbar.AlphaOptimizedFrameLayout>
|
||||
</com.android.systemui.statusbar.AlphaOptimizedLinearLayout>
|
||||
|
||||
<LinearLayout android:id="@+id/system_icon_area"
|
||||
<com.android.systemui.statusbar.AlphaOptimizedLinearLayout android:id="@+id/system_icon_area"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="horizontal"
|
||||
@@ -109,7 +117,7 @@
|
||||
android:paddingStart="6dip"
|
||||
android:gravity="center_vertical|start"
|
||||
/>
|
||||
</LinearLayout>
|
||||
</com.android.systemui.statusbar.AlphaOptimizedLinearLayout>
|
||||
</LinearLayout>
|
||||
|
||||
<ViewStub
|
||||
|
||||
@@ -56,6 +56,12 @@
|
||||
android:clipToPadding="false"
|
||||
android:clipChildren="false">
|
||||
|
||||
<com.android.systemui.statusbar.stack.NotificationStackScrollLayout
|
||||
android:id="@+id/notification_stack_scroller"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginBottom="@dimen/close_handle_underlap"/>
|
||||
|
||||
<com.android.systemui.statusbar.phone.ObservableScrollView
|
||||
android:id="@+id/scroll_view"
|
||||
android:layout_width="match_parent"
|
||||
@@ -82,12 +88,6 @@
|
||||
</LinearLayout>
|
||||
</com.android.systemui.statusbar.phone.ObservableScrollView>
|
||||
|
||||
<com.android.systemui.statusbar.stack.NotificationStackScrollLayout
|
||||
android:id="@+id/notification_stack_scroller"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginBottom="@dimen/close_handle_underlap"/>
|
||||
|
||||
</com.android.systemui.statusbar.phone.NotificationsQuickSettingsContainer>
|
||||
|
||||
<include layout="@layout/status_bar_expanded_header" />
|
||||
|
||||
@@ -155,10 +155,6 @@
|
||||
<!-- The size of the gesture span needed to activate the "pull" notification expansion -->
|
||||
<dimen name="pull_span_min">25dp</dimen>
|
||||
|
||||
<!-- How far to slide the panel out when you touch it -->
|
||||
<!-- For phones, this is close_handle_height + header_height -->
|
||||
<dimen name="peek_height">84dp</dimen>
|
||||
|
||||
<dimen name="qs_tile_height">88dp</dimen>
|
||||
<dimen name="qs_tile_icon_size">28dp</dimen>
|
||||
<dimen name="qs_tile_text_size">12sp</dimen>
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.AttributeSet;
|
||||
import android.widget.FrameLayout;
|
||||
import android.widget.LinearLayout;
|
||||
|
||||
/**
|
||||
* A frame layout which does not have overlapping renderings commands and therefore does not need a
|
||||
* layer when alpha is changed.
|
||||
*/
|
||||
public class AlphaOptimizedFrameLayout extends FrameLayout
|
||||
{
|
||||
public AlphaOptimizedFrameLayout(Context context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
public AlphaOptimizedFrameLayout(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
}
|
||||
|
||||
public AlphaOptimizedFrameLayout(Context context, AttributeSet attrs, int defStyleAttr) {
|
||||
super(context, attrs, defStyleAttr);
|
||||
}
|
||||
|
||||
public AlphaOptimizedFrameLayout(Context context, AttributeSet attrs, int defStyleAttr,
|
||||
int defStyleRes) {
|
||||
super(context, attrs, defStyleAttr, defStyleRes);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasOverlappingRendering() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.View;
|
||||
import android.widget.LinearLayout;
|
||||
|
||||
/**
|
||||
* A linear layout which does not have overlapping renderings commands and therefore does not need a
|
||||
* layer when alpha is changed.
|
||||
*/
|
||||
public class AlphaOptimizedLinearLayout extends LinearLayout
|
||||
{
|
||||
public AlphaOptimizedLinearLayout(Context context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
public AlphaOptimizedLinearLayout(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
}
|
||||
|
||||
public AlphaOptimizedLinearLayout(Context context, AttributeSet attrs, int defStyleAttr) {
|
||||
super(context, attrs, defStyleAttr);
|
||||
}
|
||||
|
||||
public AlphaOptimizedLinearLayout(Context context, AttributeSet attrs, int defStyleAttr,
|
||||
int defStyleRes) {
|
||||
super(context, attrs, defStyleAttr, defStyleRes);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasOverlappingRendering() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -425,7 +425,7 @@ public abstract class BaseStatusBar extends SystemUI implements
|
||||
|
||||
createAndAddWindows();
|
||||
|
||||
disable(switches[0]);
|
||||
disable(switches[0], false /* animate */);
|
||||
setSystemUiVisibility(switches[1], 0xffffffff);
|
||||
topAppWindowChanged(switches[2] != 0);
|
||||
// StatusBarManagerService has a back up of IME token and it's restored here.
|
||||
|
||||
@@ -19,7 +19,6 @@ package com.android.systemui.statusbar;
|
||||
import android.os.Handler;
|
||||
import android.os.IBinder;
|
||||
import android.os.Message;
|
||||
import android.service.notification.StatusBarNotification;
|
||||
|
||||
import com.android.internal.statusbar.IStatusBar;
|
||||
import com.android.internal.statusbar.StatusBarIcon;
|
||||
@@ -77,7 +76,7 @@ public class CommandQueue extends IStatusBar.Stub {
|
||||
public void updateIcon(String slot, int index, int viewIndex,
|
||||
StatusBarIcon old, StatusBarIcon icon);
|
||||
public void removeIcon(String slot, int index, int viewIndex);
|
||||
public void disable(int state);
|
||||
public void disable(int state, boolean animate);
|
||||
public void animateExpandNotificationsPanel();
|
||||
public void animateCollapsePanels(int flags);
|
||||
public void animateExpandSettingsPanel();
|
||||
@@ -254,7 +253,7 @@ public class CommandQueue extends IStatusBar.Stub {
|
||||
break;
|
||||
}
|
||||
case MSG_DISABLE:
|
||||
mCallbacks.disable(msg.arg1);
|
||||
mCallbacks.disable(msg.arg1, true /* animate */);
|
||||
break;
|
||||
case MSG_EXPAND_NOTIFICATIONS:
|
||||
mCallbacks.animateExpandNotificationsPanel();
|
||||
|
||||
@@ -123,6 +123,7 @@ public abstract class ExpandableView extends FrameLayout {
|
||||
* @param notifyListeners Whether the listener should be informed about the change.
|
||||
*/
|
||||
public void setActualHeight(int actualHeight, boolean notifyListeners) {
|
||||
mActualHeightInitialized = true;
|
||||
mActualHeight = actualHeight;
|
||||
if (notifyListeners) {
|
||||
notifyHeightChanged();
|
||||
@@ -130,7 +131,6 @@ public abstract class ExpandableView extends FrameLayout {
|
||||
}
|
||||
|
||||
public void setActualHeight(int actualHeight) {
|
||||
mActualHeightInitialized = true;
|
||||
setActualHeight(actualHeight, true);
|
||||
}
|
||||
|
||||
|
||||
@@ -29,8 +29,9 @@ import android.view.animation.PathInterpolator;
|
||||
public class FlingAnimationUtils {
|
||||
|
||||
private static final float LINEAR_OUT_SLOW_IN_X2 = 0.35f;
|
||||
private static final float LINEAR_OUT_FASTER_IN_Y2_MIN = 0.7f;
|
||||
private static final float LINEAR_OUT_FASTER_IN_Y2_MAX = 1f;
|
||||
private static final float LINEAR_OUT_FASTER_IN_X2 = 0.5f;
|
||||
private static final float LINEAR_OUT_FASTER_IN_Y2_MIN = 0.4f;
|
||||
private static final float LINEAR_OUT_FASTER_IN_Y2_MAX = 0.5f;
|
||||
private static final float MIN_VELOCITY_DP_PER_SECOND = 250;
|
||||
private static final float HIGH_VELOCITY_DP_PER_SECOND = 3000;
|
||||
|
||||
@@ -203,9 +204,8 @@ public class FlingAnimationUtils {
|
||||
float velAbs = Math.abs(velocity);
|
||||
float y2 = calculateLinearOutFasterInY2(velAbs);
|
||||
|
||||
// The gradient at the start of the curve is just y2.
|
||||
float startGradient = y2;
|
||||
Interpolator mLinearOutFasterIn = new PathInterpolator(0, 0, 1, y2);
|
||||
float startGradient = y2 / LINEAR_OUT_FASTER_IN_X2;
|
||||
Interpolator mLinearOutFasterIn = new PathInterpolator(0, 0, LINEAR_OUT_FASTER_IN_X2, y2);
|
||||
float durationSeconds = startGradient * diff / velAbs;
|
||||
if (durationSeconds <= maxLengthSeconds) {
|
||||
mAnimatorProperties.interpolator = mLinearOutFasterIn;
|
||||
|
||||
@@ -237,6 +237,11 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL
|
||||
return mIndicationText;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasOverlappingRendering() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMethodSecureChanged(boolean methodSecure) {
|
||||
updateTrust();
|
||||
|
||||
@@ -55,6 +55,7 @@ public class NotificationPanelView extends PanelView implements
|
||||
private static final int CAP_HEIGHT = 1456;
|
||||
private static final int FONT_HEIGHT = 2163;
|
||||
|
||||
private static final float HEADER_RUBBERBAND_FACTOR = 2.15f;
|
||||
private static final float LOCK_ICON_ACTIVE_SCALE = 1.2f;
|
||||
|
||||
private KeyguardPageSwipeHelper mPageSwiper;
|
||||
@@ -97,7 +98,6 @@ public class NotificationPanelView extends PanelView implements
|
||||
private ValueAnimator mQsExpansionAnimator;
|
||||
private FlingAnimationUtils mFlingAnimationUtils;
|
||||
private int mStatusBarMinHeight;
|
||||
private boolean mHeaderHidden;
|
||||
private boolean mUnlockIconActive;
|
||||
private int mNotificationsHeaderCollideDistance;
|
||||
private int mUnlockMoveDistance;
|
||||
@@ -207,9 +207,7 @@ public class NotificationPanelView extends PanelView implements
|
||||
boolean animate = mNotificationStackScroller.isAddOrRemoveAnimationPending();
|
||||
int stackScrollerPadding;
|
||||
if (mStatusBar.getBarState() != StatusBarState.KEYGUARD) {
|
||||
int bottom = mStackScrollerOverscrolling
|
||||
? mHeader.getCollapsedHeight()
|
||||
: mHeader.getBottom();
|
||||
int bottom = mHeader.getCollapsedHeight();
|
||||
stackScrollerPadding = bottom + mQsPeekHeight
|
||||
+ mNotificationTopPadding;
|
||||
mTopPaddingAdjustment = 0;
|
||||
@@ -562,6 +560,10 @@ public class NotificationPanelView extends PanelView implements
|
||||
}
|
||||
|
||||
public void setKeyguardShowing(boolean keyguardShowing) {
|
||||
if (!mKeyguardShowing && keyguardShowing) {
|
||||
setQsTranslation(mQsExpansionHeight);
|
||||
mHeader.setTranslationY(0f);
|
||||
}
|
||||
mKeyguardShowing = keyguardShowing;
|
||||
updateQsState();
|
||||
}
|
||||
@@ -602,10 +604,9 @@ public class NotificationPanelView extends PanelView implements
|
||||
}
|
||||
|
||||
private void setQsTranslation(float height) {
|
||||
mQsContainer.setY(height - mQsContainer.getHeight());
|
||||
mQsContainer.setY(height - mQsContainer.getHeight() + getHeaderTranslation());
|
||||
}
|
||||
|
||||
|
||||
private void requestScrollerTopPaddingUpdate(boolean animate) {
|
||||
mNotificationStackScroller.updateTopPadding(mQsExpansionHeight,
|
||||
mScrollView.getScrollY(),
|
||||
@@ -728,6 +729,11 @@ public class NotificationPanelView extends PanelView implements
|
||||
|
||||
@Override
|
||||
protected int getMaxPanelHeight() {
|
||||
if (mStatusBar.getBarState() != StatusBarState.KEYGUARD
|
||||
&& mNotificationStackScroller.getNotGoneChildCount() == 0) {
|
||||
return (int) ((mQsMinExpansionHeight + getOverExpansionAmount())
|
||||
* HEADER_RUBBERBAND_FACTOR);
|
||||
}
|
||||
// TODO: Figure out transition for collapsing when QS is open, adjust height here.
|
||||
int emptyBottomMargin = mNotificationStackScroller.getEmptyBottomMargin();
|
||||
int maxHeight = mNotificationStackScroller.getHeight() - emptyBottomMargin
|
||||
@@ -746,8 +752,22 @@ public class NotificationPanelView extends PanelView implements
|
||||
positionClockAndNotifications();
|
||||
}
|
||||
mNotificationStackScroller.setStackHeight(expandedHeight);
|
||||
updateKeyguardHeaderVisibility();
|
||||
updateHeader();
|
||||
updateUnlockIcon();
|
||||
updateNotificationTranslucency();
|
||||
}
|
||||
|
||||
private void updateNotificationTranslucency() {
|
||||
float alpha = (mNotificationStackScroller.getNotificationsTopY()
|
||||
+ mNotificationStackScroller.getItemHeight())
|
||||
/ (mQsMinExpansionHeight
|
||||
+ mNotificationStackScroller.getItemHeight() / 2);
|
||||
alpha = Math.max(0, Math.min(alpha, 1));
|
||||
alpha = (float) Math.pow(alpha, 0.75);
|
||||
|
||||
// TODO: Draw a rect with DST_OUT over the notifications to achieve the same effect -
|
||||
// this would be much more efficient.
|
||||
mNotificationStackScroller.setAlpha(alpha);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -786,51 +806,61 @@ public class NotificationPanelView extends PanelView implements
|
||||
/**
|
||||
* Hides the header when notifications are colliding with it.
|
||||
*/
|
||||
private void updateKeyguardHeaderVisibility() {
|
||||
private void updateHeader() {
|
||||
if (mStatusBar.getBarState() == StatusBarState.KEYGUARD
|
||||
|| mStatusBar.getBarState() == StatusBarState.SHADE_LOCKED) {
|
||||
boolean hidden;
|
||||
if (mStatusBar.getBarState() == StatusBarState.KEYGUARD) {
|
||||
|
||||
// When on Keyguard, we hide the header as soon as the top card of the notification
|
||||
// stack scroller is close enough (collision distance) to the bottom of the header.
|
||||
hidden = mNotificationStackScroller.getNotificationsTopY()
|
||||
<= mHeader.getBottom() + mNotificationsHeaderCollideDistance;
|
||||
} else {
|
||||
|
||||
// In SHADE_LOCKED, the top card is already really close to the header. Hide it as
|
||||
// soon as we start translating the stack.
|
||||
hidden = mNotificationStackScroller.getTranslationY() < 0;
|
||||
}
|
||||
|
||||
if (hidden && !mHeaderHidden) {
|
||||
mHeader.animate()
|
||||
.alpha(0f)
|
||||
.withLayer()
|
||||
.translationY(-mHeader.getHeight()/2)
|
||||
.setInterpolator(mFastOutLinearInterpolator)
|
||||
.setDuration(200);
|
||||
} else if (!hidden && mHeaderHidden) {
|
||||
mHeader.animate()
|
||||
.alpha(1f)
|
||||
.withLayer()
|
||||
.translationY(0)
|
||||
.setInterpolator(mLinearOutSlowInInterpolator)
|
||||
.setDuration(200);
|
||||
}
|
||||
mHeaderHidden = hidden;
|
||||
updateHeaderKeyguard();
|
||||
} else {
|
||||
mHeader.animate().cancel();
|
||||
mHeader.setAlpha(1f);
|
||||
mHeader.setTranslationY(0f);
|
||||
if (mHeader.getLayerType() != LAYER_TYPE_NONE) {
|
||||
mHeader.setLayerType(LAYER_TYPE_NONE, null);
|
||||
}
|
||||
mHeaderHidden = false;
|
||||
updateHeaderShade();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void updateHeaderShade() {
|
||||
mHeader.setAlpha(1f);
|
||||
mHeader.setTranslationY(getHeaderTranslation());
|
||||
setQsTranslation(mQsExpansionHeight);
|
||||
}
|
||||
|
||||
private float getHeaderTranslation() {
|
||||
if (mStatusBar.getBarState() == StatusBarState.KEYGUARD
|
||||
|| mStatusBar.getBarState() == StatusBarState.SHADE_LOCKED) {
|
||||
return 0;
|
||||
}
|
||||
if (mNotificationStackScroller.getNotGoneChildCount() == 0) {
|
||||
if (mExpandedHeight / HEADER_RUBBERBAND_FACTOR >= mQsMinExpansionHeight) {
|
||||
return 0;
|
||||
} else {
|
||||
return mExpandedHeight / HEADER_RUBBERBAND_FACTOR - mQsMinExpansionHeight;
|
||||
}
|
||||
}
|
||||
return Math.min(0, mNotificationStackScroller.getTranslationY()) / HEADER_RUBBERBAND_FACTOR;
|
||||
}
|
||||
|
||||
private void updateHeaderKeyguard() {
|
||||
mHeader.setTranslationY(0f);
|
||||
float alpha;
|
||||
if (mStatusBar.getBarState() == StatusBarState.KEYGUARD) {
|
||||
|
||||
// When on Keyguard, we hide the header as soon as the top card of the notification
|
||||
// stack scroller is close enough (collision distance) to the bottom of the header.
|
||||
alpha = mNotificationStackScroller.getNotificationsTopY()
|
||||
/
|
||||
(mQsMinExpansionHeight + mNotificationsHeaderCollideDistance);
|
||||
|
||||
} else {
|
||||
|
||||
// In SHADE_LOCKED, the top card is already really close to the header. Hide it as
|
||||
// soon as we start translating the stack.
|
||||
alpha = mNotificationStackScroller.getNotificationsTopY() / mQsMinExpansionHeight;
|
||||
}
|
||||
alpha = Math.max(0, Math.min(alpha, 1));
|
||||
alpha = (float) Math.pow(alpha, 0.75);
|
||||
mHeader.setAlpha(alpha);
|
||||
mKeyguardBottomArea.setAlpha(alpha);
|
||||
setQsTranslation(mQsExpansionHeight);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onExpandingStarted() {
|
||||
super.onExpandingStarted();
|
||||
@@ -1007,4 +1037,13 @@ public class NotificationPanelView extends PanelView implements
|
||||
? mKeyguardBottomArea.getPhoneImageView()
|
||||
: mKeyguardBottomArea.getCameraImageView();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected float getPeekHeight() {
|
||||
if (mNotificationStackScroller.getNotGoneChildCount() > 0) {
|
||||
return mNotificationStackScroller.getPeekHeight();
|
||||
} else {
|
||||
return mQsMinExpansionHeight;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -93,15 +93,14 @@ public abstract class PanelView extends FrameLayout {
|
||||
}
|
||||
|
||||
private void runPeekAnimation() {
|
||||
mPeekHeight = getPeekHeight();
|
||||
if (DEBUG) logf("peek to height=%.1f", mPeekHeight);
|
||||
if (mHeightAnimator != null) {
|
||||
return;
|
||||
}
|
||||
if (mPeekAnimator == null) {
|
||||
mPeekAnimator = ObjectAnimator.ofFloat(this,
|
||||
"expandedHeight", mPeekHeight)
|
||||
.setDuration(250);
|
||||
}
|
||||
mPeekAnimator = ObjectAnimator.ofFloat(this,
|
||||
"expandedHeight", mPeekHeight)
|
||||
.setDuration(250);
|
||||
mPeekAnimator.start();
|
||||
}
|
||||
|
||||
@@ -115,9 +114,6 @@ public abstract class PanelView extends FrameLayout {
|
||||
|
||||
protected void loadDimens() {
|
||||
final Resources res = getContext().getResources();
|
||||
mPeekHeight = res.getDimension(R.dimen.peek_height)
|
||||
+ getPaddingBottom(); // our window might have a dropshadow
|
||||
|
||||
final ViewConfiguration configuration = ViewConfiguration.get(getContext());
|
||||
mTouchSlop = configuration.getScaledTouchSlop();
|
||||
mHintDistance = res.getDimension(R.dimen.hint_move_distance);
|
||||
@@ -758,4 +754,6 @@ public abstract class PanelView extends FrameLayout {
|
||||
}
|
||||
|
||||
public abstract void resetViews();
|
||||
|
||||
protected abstract float getPeekHeight();
|
||||
}
|
||||
|
||||
@@ -31,6 +31,7 @@ import static com.android.systemui.statusbar.phone.BarTransitions.MODE_TRANSPARE
|
||||
|
||||
import android.animation.Animator;
|
||||
import android.animation.AnimatorListenerAdapter;
|
||||
import android.animation.ObjectAnimator;
|
||||
import android.animation.TimeInterpolator;
|
||||
import android.animation.ValueAnimator;
|
||||
import android.app.ActivityManager;
|
||||
@@ -221,6 +222,8 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
|
||||
LinearLayout mStatusIcons;
|
||||
// the icons themselves
|
||||
IconMerger mNotificationIcons;
|
||||
View mNotificationIconArea;
|
||||
|
||||
// [+>
|
||||
View mMoreIcon;
|
||||
|
||||
@@ -300,16 +303,6 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
|
||||
: null;
|
||||
|
||||
private int mNavigationIconHints = 0;
|
||||
private final Animator.AnimatorListener mMakeIconsInvisible = new AnimatorListenerAdapter() {
|
||||
@Override
|
||||
public void onAnimationEnd(Animator animation) {
|
||||
// double-check to avoid races
|
||||
if (mStatusBarContents.getAlpha() == 0) {
|
||||
if (DEBUG) Log.d(TAG, "makeIconsInvisible");
|
||||
mStatusBarContents.setVisibility(View.INVISIBLE);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// ensure quick settings is disabled until the current user makes it through the setup wizard
|
||||
private boolean mUserSetup = false;
|
||||
@@ -383,8 +376,8 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
|
||||
private boolean mDozing;
|
||||
|
||||
private Interpolator mLinearOutSlowIn;
|
||||
private Interpolator mAlphaOut = new PathInterpolator(0f, 0.4f, 1f, 1f);
|
||||
private Interpolator mAlphaIn = new PathInterpolator(0f, 0f, 0.8f, 1f);
|
||||
private Interpolator mAlphaIn = new PathInterpolator(0f, 0.2f, 1f, 1f);
|
||||
private Interpolator mAlphaOut = new PathInterpolator(0f, 0f, 0.8f, 1f);
|
||||
|
||||
private final OnChildLocationsChangedListener mOnChildLocationsChangedListener =
|
||||
new OnChildLocationsChangedListener() {
|
||||
@@ -608,6 +601,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
|
||||
mSystemIconArea = (LinearLayout) mStatusBarView.findViewById(R.id.system_icon_area);
|
||||
mSystemIcons = (LinearLayout) mStatusBarView.findViewById(R.id.system_icons);
|
||||
mStatusIcons = (LinearLayout)mStatusBarView.findViewById(R.id.statusIcons);
|
||||
mNotificationIconArea = mStatusBarView.findViewById(R.id.notification_icon_area_inner);
|
||||
mNotificationIcons = (IconMerger)mStatusBarView.findViewById(R.id.notificationIcons);
|
||||
mMoreIcon = mStatusBarView.findViewById(R.id.moreIcon);
|
||||
mNotificationIcons.setOverflowIndicator(mMoreIcon);
|
||||
@@ -1423,7 +1417,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
|
||||
/**
|
||||
* State is one or more of the DISABLE constants from StatusBarManager.
|
||||
*/
|
||||
public void disable(int state) {
|
||||
public void disable(int state, boolean animate) {
|
||||
mDisabledUnmodified = state;
|
||||
state = adjustDisableFlags(state);
|
||||
final int old = mDisabled;
|
||||
@@ -1461,9 +1455,9 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
|
||||
if ((diff & StatusBarManager.DISABLE_SYSTEM_INFO) != 0) {
|
||||
mSystemIconArea.animate().cancel();
|
||||
if ((state & StatusBarManager.DISABLE_SYSTEM_INFO) != 0) {
|
||||
animateStatusBarHide(mSystemIconArea);
|
||||
animateStatusBarHide(mSystemIconArea, animate);
|
||||
} else {
|
||||
animateStatusBarShow(mSystemIconArea);
|
||||
animateStatusBarShow(mSystemIconArea, animate);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1496,9 +1490,9 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
|
||||
if (mTicking) {
|
||||
haltTicker();
|
||||
}
|
||||
animateStatusBarHide(mNotificationIcons);
|
||||
animateStatusBarHide(mNotificationIconArea, animate);
|
||||
} else {
|
||||
animateStatusBarShow(mNotificationIcons);
|
||||
animateStatusBarShow(mNotificationIconArea, animate);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1506,35 +1500,49 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
|
||||
/**
|
||||
* Animates {@code v}, a view that is part of the status bar, out.
|
||||
*/
|
||||
private void animateStatusBarHide(View v) {
|
||||
private void animateStatusBarHide(final View v, boolean animate) {
|
||||
v.animate().cancel();
|
||||
if (!animate) {
|
||||
v.setAlpha(0f);
|
||||
v.setVisibility(View.INVISIBLE);
|
||||
return;
|
||||
}
|
||||
v.animate()
|
||||
.alpha(0f)
|
||||
.withLayer()
|
||||
.setDuration(160)
|
||||
.setInterpolator(mAlphaIn)
|
||||
.setStartDelay(0)
|
||||
.setListener(mMakeIconsInvisible)
|
||||
.start();
|
||||
.setInterpolator(mAlphaOut)
|
||||
.withEndAction(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
v.setVisibility(View.INVISIBLE);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Animates {@code v}, a view that is part of the status bar, in.
|
||||
*/
|
||||
private void animateStatusBarShow(View v) {
|
||||
private void animateStatusBarShow(View v, boolean animate) {
|
||||
v.animate().cancel();
|
||||
v.setVisibility(View.VISIBLE);
|
||||
if (!animate) {
|
||||
v.setAlpha(1f);
|
||||
return;
|
||||
}
|
||||
v.animate()
|
||||
.alpha(1f)
|
||||
.withLayer()
|
||||
.setInterpolator(mAlphaOut)
|
||||
.setDuration(320)
|
||||
.setStartDelay(0);
|
||||
.setInterpolator(mAlphaIn)
|
||||
.setStartDelay(50);
|
||||
|
||||
// Synchronize the motion with the Keyguard fading if necessary.
|
||||
if (mKeyguardFadingAway) {
|
||||
v.animate()
|
||||
.setDuration(mKeyguardFadingAwayDuration)
|
||||
.setInterpolator(mLinearOutSlowIn)
|
||||
.setStartDelay(mKeyguardFadingAwayDelay);
|
||||
.setStartDelay(mKeyguardFadingAwayDelay)
|
||||
.start();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1636,7 +1644,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
|
||||
|
||||
visibilityChanged(true);
|
||||
mWaitingForKeyguardExit = false;
|
||||
disable(mDisabledUnmodified);
|
||||
disable(mDisabledUnmodified, !force /* animate */);
|
||||
setInteracting(StatusBarManager.WINDOW_STATUS_BAR, true);
|
||||
}
|
||||
|
||||
@@ -1810,10 +1818,6 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
|
||||
// Shrink the window to the size of the status bar only
|
||||
mStatusBarWindowManager.setStatusBarExpanded(false);
|
||||
|
||||
if ((mDisabled & StatusBarManager.DISABLE_NOTIFICATION_ICONS) == 0) {
|
||||
setNotificationIconVisibility(true, com.android.internal.R.anim.fade_in);
|
||||
}
|
||||
|
||||
// Close any "App info" popups that might have snuck on-screen
|
||||
dismissPopups();
|
||||
|
||||
@@ -1824,7 +1828,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
|
||||
|
||||
setInteracting(StatusBarManager.WINDOW_STATUS_BAR, false);
|
||||
showBouncer();
|
||||
disable(mDisabledUnmodified);
|
||||
disable(mDisabledUnmodified, true /* animate */);
|
||||
}
|
||||
|
||||
public boolean interceptTouchEvent(MotionEvent event) {
|
||||
@@ -2337,15 +2341,6 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
|
||||
mStatusBarWindowManager.add(mStatusBarWindow, getStatusBarHeight());
|
||||
}
|
||||
|
||||
void setNotificationIconVisibility(boolean visible, int anim) {
|
||||
int old = mNotificationIcons.getVisibility();
|
||||
int v = visible ? View.VISIBLE : View.INVISIBLE;
|
||||
if (old != v) {
|
||||
mNotificationIcons.setVisibility(v);
|
||||
mNotificationIcons.startAnimation(loadAnim(anim, null));
|
||||
}
|
||||
}
|
||||
|
||||
static final float saturate(float a) {
|
||||
return a < 0f ? 0f : (a > 1f ? 1f : a);
|
||||
}
|
||||
@@ -2835,7 +2830,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
|
||||
mKeyguardFadingAwayDelay = delay;
|
||||
mKeyguardFadingAwayDuration = fadeoutDuration;
|
||||
mWaitingForKeyguardExit = false;
|
||||
disable(mDisabledUnmodified);
|
||||
disable(mDisabledUnmodified, true /* animate */);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -3093,7 +3088,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
|
||||
@Override
|
||||
public void setBouncerShowing(boolean bouncerShowing) {
|
||||
super.setBouncerShowing(bouncerShowing);
|
||||
disable(mDisabledUnmodified);
|
||||
disable(mDisabledUnmodified, true /* animate */);
|
||||
}
|
||||
|
||||
public void onScreenTurnedOff() {
|
||||
|
||||
@@ -111,7 +111,14 @@ public class PhoneStatusBarView extends PanelBar {
|
||||
@Override
|
||||
public void onAllPanelsCollapsed() {
|
||||
super.onAllPanelsCollapsed();
|
||||
mBar.makeExpandedInvisible();
|
||||
|
||||
// Close the status bar in the next frame so we can show the end of the animation.
|
||||
postOnAnimation(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
mBar.makeExpandedInvisible();
|
||||
}
|
||||
});
|
||||
mLastFullyOpenedPanel = null;
|
||||
}
|
||||
|
||||
@@ -166,27 +173,7 @@ public class PhoneStatusBarView extends PanelBar {
|
||||
@Override
|
||||
public void panelExpansionChanged(PanelView panel, float frac) {
|
||||
super.panelExpansionChanged(panel, frac);
|
||||
|
||||
if (DEBUG) {
|
||||
Log.v(TAG, "panelExpansionChanged: f=" + frac);
|
||||
}
|
||||
|
||||
mScrimController.setPanelExpansion(frac);
|
||||
|
||||
// fade out the panel as it gets buried into the status bar to avoid overdrawing the
|
||||
// status bar on the last frame of a close animation
|
||||
final int H = mBar.getStatusBarHeight();
|
||||
final float ph = panel.getExpandedHeight() + panel.getPaddingBottom();
|
||||
float alpha = 1f;
|
||||
if (ph < 2*H) {
|
||||
if (ph < H) alpha = 0f;
|
||||
else alpha = (ph - H) / H;
|
||||
alpha = alpha * alpha; // get there faster
|
||||
}
|
||||
if (panel.getAlpha() != alpha) {
|
||||
panel.setAlpha(alpha);
|
||||
}
|
||||
|
||||
mBar.updateCarrierLabelVisibility(false);
|
||||
mBar.userActivity();
|
||||
}
|
||||
|
||||
@@ -405,4 +405,9 @@ public class StatusBarHeaderView extends RelativeLayout implements View.OnClickL
|
||||
updateVisibilities();
|
||||
updateSystemIconsLayoutParams();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasOverlappingRendering() {
|
||||
return !mKeyguardShowing || mExpanded;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -420,7 +420,7 @@ public class NotificationStackScrollLayout extends ViewGroup
|
||||
int bottomStackPeekSize = mBottomStackPeekSize;
|
||||
int minStackHeight = itemHeight + bottomStackPeekSize;
|
||||
int stackHeight;
|
||||
if (newStackHeight - mTopPadding >= minStackHeight) {
|
||||
if (newStackHeight - mTopPadding >= minStackHeight || getNotGoneChildCount() == 0) {
|
||||
setTranslationY(0);
|
||||
stackHeight = newStackHeight;
|
||||
} else {
|
||||
@@ -1266,6 +1266,10 @@ public class NotificationStackScrollLayout extends ViewGroup
|
||||
setTopPadding(clampPadding((int) start), animate);
|
||||
}
|
||||
|
||||
public int getPeekHeight() {
|
||||
return mIntrinsicPadding + mCollapsedSize + mBottomStackPeekSize;
|
||||
}
|
||||
|
||||
private int clampPadding(int desiredPadding) {
|
||||
return Math.max(desiredPadding, mIntrinsicPadding);
|
||||
}
|
||||
|
||||
@@ -59,7 +59,7 @@ public class TvStatusBar extends BaseStatusBar {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void disable(int state) {
|
||||
public void disable(int state, boolean animate) {
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
Reference in New Issue
Block a user