Merge changes from topic "notif_smooth_dismissal" into sc-dev am: 4721ef7c65 am: 1c82804dca
Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/14965033 Change-Id: Ie8b196593432e30a0be2487dfede11cb921faba0
This commit is contained in:
@@ -396,10 +396,6 @@
|
|||||||
<!-- Whether or not the notifications should always fade as they are dismissed. -->
|
<!-- Whether or not the notifications should always fade as they are dismissed. -->
|
||||||
<bool name="config_fadeNotificationsOnDismiss">false</bool>
|
<bool name="config_fadeNotificationsOnDismiss">false</bool>
|
||||||
|
|
||||||
<!-- Whether or not the parent of the notification row itself is being translated when swiped or
|
|
||||||
its children views. If true, then the contents are translated and vice versa. -->
|
|
||||||
<bool name="config_translateNotificationContentsOnSwipe">true</bool>
|
|
||||||
|
|
||||||
<!-- Whether or not the fade on the notification is based on the amount that it has been swiped
|
<!-- Whether or not the fade on the notification is based on the amount that it has been swiped
|
||||||
off-screen. -->
|
off-screen. -->
|
||||||
<bool name="config_fadeDependingOnAmountSwiped">false</bool>
|
<bool name="config_fadeDependingOnAmountSwiped">false</bool>
|
||||||
|
|||||||
@@ -391,9 +391,9 @@ public class SwipeHelper implements Gefingerpoken {
|
|||||||
boolean animateLeft = (Math.abs(velocity) > getEscapeVelocity() && velocity < 0) ||
|
boolean animateLeft = (Math.abs(velocity) > getEscapeVelocity() && velocity < 0) ||
|
||||||
(getTranslation(animView) < 0 && !isDismissAll);
|
(getTranslation(animView) < 0 && !isDismissAll);
|
||||||
if (animateLeft || animateLeftForRtl || animateUpForMenu) {
|
if (animateLeft || animateLeftForRtl || animateUpForMenu) {
|
||||||
newPos = -getSize(animView);
|
newPos = -getTotalTranslationLength(animView);
|
||||||
} else {
|
} else {
|
||||||
newPos = getSize(animView);
|
newPos = getTotalTranslationLength(animView);
|
||||||
}
|
}
|
||||||
long duration;
|
long duration;
|
||||||
if (fixedDuration == 0) {
|
if (fixedDuration == 0) {
|
||||||
@@ -469,6 +469,15 @@ public class SwipeHelper implements Gefingerpoken {
|
|||||||
anim.start();
|
anim.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the total translation length where we want to swipe to when dismissing the view. By
|
||||||
|
* default this is the size of the view, but can also be larger.
|
||||||
|
* @param animView the view to ask about
|
||||||
|
*/
|
||||||
|
protected float getTotalTranslationLength(View animView) {
|
||||||
|
return getSize(animView);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called to update the dismiss animation.
|
* Called to update the dismiss animation.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -71,11 +71,11 @@ public final class NotificationClicker implements View.OnClickListener {
|
|||||||
// Check if the notification is displaying the menu, if so slide notification back
|
// Check if the notification is displaying the menu, if so slide notification back
|
||||||
if (isMenuVisible(row)) {
|
if (isMenuVisible(row)) {
|
||||||
mLogger.logMenuVisible(entry);
|
mLogger.logMenuVisible(entry);
|
||||||
row.animateTranslateNotification(0);
|
row.animateResetTranslation();
|
||||||
return;
|
return;
|
||||||
} else if (row.isChildInGroup() && isMenuVisible(row.getNotificationParent())) {
|
} else if (row.isChildInGroup() && isMenuVisible(row.getNotificationParent())) {
|
||||||
mLogger.logParentMenuVisible(entry);
|
mLogger.logParentMenuVisible(entry);
|
||||||
row.getNotificationParent().animateTranslateNotification(0);
|
row.getNotificationParent().animateResetTranslation();
|
||||||
return;
|
return;
|
||||||
} else if (row.isSummaryWithChildren() && row.areChildrenExpanded()) {
|
} else if (row.isSummaryWithChildren() && row.areChildrenExpanded()) {
|
||||||
// We never want to open the app directly if the user clicks in between
|
// We never want to open the app directly if the user clicks in between
|
||||||
|
|||||||
@@ -874,7 +874,7 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
|
|||||||
@Override
|
@Override
|
||||||
protected boolean handleSlideBack() {
|
protected boolean handleSlideBack() {
|
||||||
if (mMenuRow != null && mMenuRow.isMenuVisible()) {
|
if (mMenuRow != null && mMenuRow.isMenuVisible()) {
|
||||||
animateTranslateNotification(0 /* targetLeft */);
|
animateResetTranslation();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
@@ -1711,12 +1711,9 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
|
|||||||
mChildrenContainer.setContainingNotification(ExpandableNotificationRow.this);
|
mChildrenContainer.setContainingNotification(ExpandableNotificationRow.this);
|
||||||
mChildrenContainer.onNotificationUpdated();
|
mChildrenContainer.onNotificationUpdated();
|
||||||
|
|
||||||
if (mShouldTranslateContents) {
|
|
||||||
mTranslateableViews.add(mChildrenContainer);
|
mTranslateableViews.add(mChildrenContainer);
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
if (mShouldTranslateContents) {
|
|
||||||
// Add the views that we translate to reveal the menu
|
// Add the views that we translate to reveal the menu
|
||||||
mTranslateableViews = new ArrayList<>();
|
mTranslateableViews = new ArrayList<>();
|
||||||
for (int i = 0; i < getChildCount(); i++) {
|
for (int i = 0; i < getChildCount(); i++) {
|
||||||
@@ -1726,7 +1723,6 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
|
|||||||
mTranslateableViews.remove(mChildrenContainerStub);
|
mTranslateableViews.remove(mChildrenContainerStub);
|
||||||
mTranslateableViews.remove(mGutsStub);
|
mTranslateableViews.remove(mGutsStub);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
private void doLongClickCallback() {
|
private void doLongClickCallback() {
|
||||||
doLongClickCallback(getWidth() / 2, getHeight() / 2);
|
doLongClickCallback(getWidth() / 2, getHeight() / 2);
|
||||||
@@ -1803,7 +1799,7 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
|
|||||||
mTranslateAnim.cancel();
|
mTranslateAnim.cancel();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!mShouldTranslateContents) {
|
if (mDismissUsingRowTranslationX) {
|
||||||
setTranslationX(0);
|
setTranslationX(0);
|
||||||
} else if (mTranslateableViews != null) {
|
} else if (mTranslateableViews != null) {
|
||||||
for (int i = 0; i < mTranslateableViews.size(); i++) {
|
for (int i = 0; i < mTranslateableViews.size(); i++) {
|
||||||
@@ -1865,23 +1861,47 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
|
|||||||
return mPrivateLayout.getActiveRemoteInputText();
|
return mPrivateLayout.getActiveRemoteInputText();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void animateTranslateNotification(final float leftTarget) {
|
/**
|
||||||
|
* Reset the translation with an animation.
|
||||||
|
*/
|
||||||
|
public void animateResetTranslation() {
|
||||||
if (mTranslateAnim != null) {
|
if (mTranslateAnim != null) {
|
||||||
mTranslateAnim.cancel();
|
mTranslateAnim.cancel();
|
||||||
}
|
}
|
||||||
mTranslateAnim = getTranslateViewAnimator(leftTarget, null /* updateListener */);
|
mTranslateAnim = getTranslateViewAnimator(0, null /* updateListener */);
|
||||||
if (mTranslateAnim != null) {
|
if (mTranslateAnim != null) {
|
||||||
mTranslateAnim.start();
|
mTranslateAnim.start();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the dismiss behavior of the view.
|
||||||
|
* @param usingRowTranslationX {@code true} if the view should translate using regular
|
||||||
|
* translationX, otherwise the contents will be
|
||||||
|
* translated.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void setDismissUsingRowTranslationX(boolean usingRowTranslationX) {
|
||||||
|
if (usingRowTranslationX != mDismissUsingRowTranslationX) {
|
||||||
|
// In case we were already transitioning, let's switch over!
|
||||||
|
float previousTranslation = getTranslation();
|
||||||
|
if (previousTranslation != 0) {
|
||||||
|
setTranslation(0);
|
||||||
|
}
|
||||||
|
super.setDismissUsingRowTranslationX(usingRowTranslationX);
|
||||||
|
if (previousTranslation != 0) {
|
||||||
|
setTranslation(previousTranslation);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setTranslation(float translationX) {
|
public void setTranslation(float translationX) {
|
||||||
invalidate();
|
invalidate();
|
||||||
if (isBlockingHelperShowingAndTranslationFinished()) {
|
if (isBlockingHelperShowingAndTranslationFinished()) {
|
||||||
mGuts.setTranslationX(translationX);
|
mGuts.setTranslationX(translationX);
|
||||||
return;
|
return;
|
||||||
} else if (!mShouldTranslateContents) {
|
} else if (mDismissUsingRowTranslationX) {
|
||||||
setTranslationX(translationX);
|
setTranslationX(translationX);
|
||||||
} else if (mTranslateableViews != null) {
|
} else if (mTranslateableViews != null) {
|
||||||
// Translate the group of views
|
// Translate the group of views
|
||||||
@@ -1905,7 +1925,7 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public float getTranslation() {
|
public float getTranslation() {
|
||||||
if (!mShouldTranslateContents) {
|
if (mDismissUsingRowTranslationX) {
|
||||||
return getTranslationX();
|
return getTranslationX();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2896,7 +2916,11 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
|
|||||||
float y = event.getY();
|
float y = event.getY();
|
||||||
NotificationViewWrapper wrapper = getVisibleNotificationViewWrapper();
|
NotificationViewWrapper wrapper = getVisibleNotificationViewWrapper();
|
||||||
NotificationHeaderView header = wrapper == null ? null : wrapper.getNotificationHeader();
|
NotificationHeaderView header = wrapper == null ? null : wrapper.getNotificationHeader();
|
||||||
if (header != null && header.isInTouchRect(x - getTranslation(), y)) {
|
// the extra translation only needs to be added, if we're translating the notification
|
||||||
|
// contents, otherwise the motionEvent is already at the right place due to the
|
||||||
|
// touch event system.
|
||||||
|
float translation = !mDismissUsingRowTranslationX ? getTranslation() : 0;
|
||||||
|
if (header != null && header.isInTouchRect(x - translation, y)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if ((!mIsSummaryWithChildren || shouldShowPublic())
|
if ((!mIsSummaryWithChildren || shouldShowPublic())
|
||||||
|
|||||||
@@ -71,10 +71,10 @@ public abstract class ExpandableOutlineView extends ExpandableView {
|
|||||||
private int mBackgroundTop;
|
private int mBackgroundTop;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@code true} if the children views of the {@link ExpandableOutlineView} are translated when
|
* {@code false} if the children views of the {@link ExpandableOutlineView} are translated when
|
||||||
* it is moved. Otherwise, the translation is set on the {@code ExpandableOutlineView} itself.
|
* it is moved. Otherwise, the translation is set on the {@code ExpandableOutlineView} itself.
|
||||||
*/
|
*/
|
||||||
protected boolean mShouldTranslateContents;
|
protected boolean mDismissUsingRowTranslationX = true;
|
||||||
private float[] mTmpCornerRadii = new float[8];
|
private float[] mTmpCornerRadii = new float[8];
|
||||||
|
|
||||||
private final ViewOutlineProvider mProvider = new ViewOutlineProvider() {
|
private final ViewOutlineProvider mProvider = new ViewOutlineProvider() {
|
||||||
@@ -82,7 +82,8 @@ public abstract class ExpandableOutlineView extends ExpandableView {
|
|||||||
public void getOutline(View view, Outline outline) {
|
public void getOutline(View view, Outline outline) {
|
||||||
if (!mCustomOutline && getCurrentTopRoundness() == 0.0f
|
if (!mCustomOutline && getCurrentTopRoundness() == 0.0f
|
||||||
&& getCurrentBottomRoundness() == 0.0f && !mAlwaysRoundBothCorners) {
|
&& getCurrentBottomRoundness() == 0.0f && !mAlwaysRoundBothCorners) {
|
||||||
int translation = mShouldTranslateContents ? (int) getTranslation() : 0;
|
// Only when translating just the contents, does the outline need to be shifted.
|
||||||
|
int translation = !mDismissUsingRowTranslationX ? (int) getTranslation() : 0;
|
||||||
int left = Math.max(translation, 0);
|
int left = Math.max(translation, 0);
|
||||||
int top = mClipTopAmount + mBackgroundTop;
|
int top = mClipTopAmount + mBackgroundTop;
|
||||||
int right = getWidth() + Math.min(translation, 0);
|
int right = getWidth() + Math.min(translation, 0);
|
||||||
@@ -107,7 +108,9 @@ public abstract class ExpandableOutlineView extends ExpandableView {
|
|||||||
float topRoundness = mAlwaysRoundBothCorners
|
float topRoundness = mAlwaysRoundBothCorners
|
||||||
? mOutlineRadius : getCurrentBackgroundRadiusTop();
|
? mOutlineRadius : getCurrentBackgroundRadiusTop();
|
||||||
if (!mCustomOutline) {
|
if (!mCustomOutline) {
|
||||||
int translation = mShouldTranslateContents && !ignoreTranslation
|
// The outline just needs to be shifted if we're translating the contents. Otherwise
|
||||||
|
// it's already in the right place.
|
||||||
|
int translation = !mDismissUsingRowTranslationX && !ignoreTranslation
|
||||||
? (int) getTranslation() : 0;
|
? (int) getTranslation() : 0;
|
||||||
int halfExtraWidth = (int) (mExtraWidthForClipping / 2.0f);
|
int halfExtraWidth = (int) (mExtraWidthForClipping / 2.0f);
|
||||||
left = Math.max(translation, 0) - halfExtraWidth;
|
left = Math.max(translation, 0) - halfExtraWidth;
|
||||||
@@ -196,13 +199,14 @@ public abstract class ExpandableOutlineView extends ExpandableView {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected boolean isClippingNeeded() {
|
protected boolean isClippingNeeded() {
|
||||||
return mAlwaysRoundBothCorners || mCustomOutline || getTranslation() != 0 ;
|
// When translating the contents instead of the overall view, we need to make sure we clip
|
||||||
|
// rounded to the contents.
|
||||||
|
boolean forTranslation = getTranslation() != 0 && !mDismissUsingRowTranslationX;
|
||||||
|
return mAlwaysRoundBothCorners || mCustomOutline || forTranslation;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void initDimens() {
|
private void initDimens() {
|
||||||
Resources res = getResources();
|
Resources res = getResources();
|
||||||
mShouldTranslateContents =
|
|
||||||
res.getBoolean(R.bool.config_translateNotificationContentsOnSwipe);
|
|
||||||
mOutlineRadius = res.getDimension(R.dimen.notification_shadow_radius);
|
mOutlineRadius = res.getDimension(R.dimen.notification_shadow_radius);
|
||||||
mAlwaysRoundBothCorners = res.getBoolean(R.bool.config_clipNotificationsToOutline);
|
mAlwaysRoundBothCorners = res.getBoolean(R.bool.config_clipNotificationsToOutline);
|
||||||
if (!mAlwaysRoundBothCorners) {
|
if (!mAlwaysRoundBothCorners) {
|
||||||
@@ -342,9 +346,25 @@ public abstract class ExpandableOutlineView extends ExpandableView {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the dismiss behavior of the view.
|
||||||
|
* @param usingRowTranslationX {@code true} if the view should translate using regular
|
||||||
|
* translationX, otherwise the contents will be
|
||||||
|
* translated.
|
||||||
|
*/
|
||||||
|
public void setDismissUsingRowTranslationX(boolean usingRowTranslationX) {
|
||||||
|
mDismissUsingRowTranslationX = usingRowTranslationX;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getOutlineTranslation() {
|
public int getOutlineTranslation() {
|
||||||
return mCustomOutline ? mOutlineRect.left : (int) getTranslation();
|
if (mCustomOutline) {
|
||||||
|
return mOutlineRect.left;
|
||||||
|
}
|
||||||
|
if (mDismissUsingRowTranslationX) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return (int) getTranslation();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void updateOutline() {
|
public void updateOutline() {
|
||||||
|
|||||||
@@ -425,13 +425,19 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
|
|||||||
private final Rect mBackgroundAnimationRect = new Rect();
|
private final Rect mBackgroundAnimationRect = new Rect();
|
||||||
private ArrayList<BiConsumer<Float, Float>> mExpandedHeightListeners = new ArrayList<>();
|
private ArrayList<BiConsumer<Float, Float>> mExpandedHeightListeners = new ArrayList<>();
|
||||||
private int mHeadsUpInset;
|
private int mHeadsUpInset;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The position of the scroll boundary relative to this view. This is where the notifications
|
||||||
|
* stop scrolling and will start to clip instead.
|
||||||
|
*/
|
||||||
|
private int mQsScrollBoundaryPosition;
|
||||||
private HeadsUpAppearanceController mHeadsUpAppearanceController;
|
private HeadsUpAppearanceController mHeadsUpAppearanceController;
|
||||||
private final Rect mTmpRect = new Rect();
|
private final Rect mTmpRect = new Rect();
|
||||||
private DismissListener mDismissListener;
|
private DismissListener mDismissListener;
|
||||||
private DismissAllAnimationListener mDismissAllAnimationListener;
|
private DismissAllAnimationListener mDismissAllAnimationListener;
|
||||||
private NotificationRemoteInputManager mRemoteInputManager;
|
private NotificationRemoteInputManager mRemoteInputManager;
|
||||||
private ShadeController mShadeController;
|
private ShadeController mShadeController;
|
||||||
private Runnable mOnStackYChanged;
|
private Consumer<Boolean> mOnStackYChanged;
|
||||||
|
|
||||||
protected boolean mClearAllEnabled;
|
protected boolean mClearAllEnabled;
|
||||||
|
|
||||||
@@ -471,10 +477,21 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
|
|||||||
private int mRoundedRectClippingRight;
|
private int mRoundedRectClippingRight;
|
||||||
private float[] mBgCornerRadii = new float[8];
|
private float[] mBgCornerRadii = new float[8];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether stackY should be animated in case the view is getting shorter than the scroll
|
||||||
|
* position and this scrolling will lead to the top scroll inset getting smaller.
|
||||||
|
*/
|
||||||
|
private boolean mAnimateStackYForContentHeightChange = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Are we launching a notification right now
|
* Are we launching a notification right now
|
||||||
*/
|
*/
|
||||||
private boolean mLaunchingNotification;
|
private boolean mLaunchingNotification;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Do notifications dismiss with normal transitioning
|
||||||
|
*/
|
||||||
|
private boolean mDismissUsingRowTranslationX = true;
|
||||||
private NotificationEntry mTopHeadsUpEntry;
|
private NotificationEntry mTopHeadsUpEntry;
|
||||||
private long mNumHeadsUp;
|
private long mNumHeadsUp;
|
||||||
private NotificationStackScrollLayoutController.TouchHandler mTouchHandler;
|
private NotificationStackScrollLayoutController.TouchHandler mTouchHandler;
|
||||||
@@ -528,7 +545,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
|
|||||||
mSectionsManager = notificationSectionsManager;
|
mSectionsManager = notificationSectionsManager;
|
||||||
mFeatureFlags = featureFlags;
|
mFeatureFlags = featureFlags;
|
||||||
mUnlockedScreenOffAnimationController = unlockedScreenOffAnimationController;
|
mUnlockedScreenOffAnimationController = unlockedScreenOffAnimationController;
|
||||||
mShouldUseSplitNotificationShade = shouldUseSplitNotificationShade(mFeatureFlags, res);
|
updateSplitNotificationShade();
|
||||||
mSectionsManager.initialize(this, LayoutInflater.from(context));
|
mSectionsManager.initialize(this, LayoutInflater.from(context));
|
||||||
mSections = mSectionsManager.createSectionsForBuckets();
|
mSections = mSectionsManager.createSectionsForBuckets();
|
||||||
|
|
||||||
@@ -884,6 +901,8 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
|
|||||||
mCornerRadius = res.getDimensionPixelSize(R.dimen.notification_corner_radius);
|
mCornerRadius = res.getDimensionPixelSize(R.dimen.notification_corner_radius);
|
||||||
mHeadsUpInset = mStatusBarHeight + res.getDimensionPixelSize(
|
mHeadsUpInset = mStatusBarHeight + res.getDimensionPixelSize(
|
||||||
R.dimen.heads_up_status_bar_padding);
|
R.dimen.heads_up_status_bar_padding);
|
||||||
|
mQsScrollBoundaryPosition = res.getDimensionPixelSize(
|
||||||
|
com.android.internal.R.dimen.quick_qs_offset_height);
|
||||||
}
|
}
|
||||||
|
|
||||||
void updateCornerRadius() {
|
void updateCornerRadius() {
|
||||||
@@ -983,6 +1002,9 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
|
|||||||
updateFirstAndLastBackgroundViews();
|
updateFirstAndLastBackgroundViews();
|
||||||
updateAlgorithmLayoutMinHeight();
|
updateAlgorithmLayoutMinHeight();
|
||||||
updateOwnTranslationZ();
|
updateOwnTranslationZ();
|
||||||
|
|
||||||
|
// Once the layout has finished, we don't need to animate any scrolling clampings anymore.
|
||||||
|
mAnimateStackYForContentHeightChange = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ShadeViewRefactor(RefactorComponent.STATE_RESOLVER)
|
@ShadeViewRefactor(RefactorComponent.STATE_RESOLVER)
|
||||||
@@ -1117,7 +1139,13 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
|
|||||||
private void clampScrollPosition() {
|
private void clampScrollPosition() {
|
||||||
int scrollRange = getScrollRange();
|
int scrollRange = getScrollRange();
|
||||||
if (scrollRange < mOwnScrollY) {
|
if (scrollRange < mOwnScrollY) {
|
||||||
setOwnScrollY(scrollRange);
|
boolean animateStackY = false;
|
||||||
|
if (scrollRange < getScrollAmountToScrollBoundary()
|
||||||
|
&& mAnimateStackYForContentHeightChange) {
|
||||||
|
// if the scroll boundary updates the position of the stack,
|
||||||
|
animateStackY = true;
|
||||||
|
}
|
||||||
|
setOwnScrollY(scrollRange, animateStackY);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1146,6 +1174,14 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
|
|||||||
* Apply expansion fraction to the y position and height of the notifications panel.
|
* Apply expansion fraction to the y position and height of the notifications panel.
|
||||||
*/
|
*/
|
||||||
private void updateStackPosition() {
|
private void updateStackPosition() {
|
||||||
|
updateStackPosition(false /* listenerNeedsAnimation */);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Apply expansion fraction to the y position and height of the notifications panel.
|
||||||
|
* @param listenerNeedsAnimation does the listener need to animate?
|
||||||
|
*/
|
||||||
|
private void updateStackPosition(boolean listenerNeedsAnimation) {
|
||||||
// Consider interpolating from an mExpansionStartY for use on lockscreen and AOD
|
// Consider interpolating from an mExpansionStartY for use on lockscreen and AOD
|
||||||
float endTopPosition = mTopPadding + mExtraTopInsetForFullShadeTransition
|
float endTopPosition = mTopPadding + mExtraTopInsetForFullShadeTransition
|
||||||
+ mAmbientState.getOverExpansion();
|
+ mAmbientState.getOverExpansion();
|
||||||
@@ -1153,7 +1189,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
|
|||||||
final float stackY = MathUtils.lerp(0, endTopPosition, fraction);
|
final float stackY = MathUtils.lerp(0, endTopPosition, fraction);
|
||||||
mAmbientState.setStackY(stackY);
|
mAmbientState.setStackY(stackY);
|
||||||
if (mOnStackYChanged != null) {
|
if (mOnStackYChanged != null) {
|
||||||
mOnStackYChanged.run();
|
mOnStackYChanged.accept(listenerNeedsAnimation);
|
||||||
}
|
}
|
||||||
if (mQsExpansionFraction <= 0) {
|
if (mQsExpansionFraction <= 0) {
|
||||||
final float stackEndHeight = Math.max(0f,
|
final float stackEndHeight = Math.max(0f,
|
||||||
@@ -1165,7 +1201,11 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void setOnStackYChanged(Runnable onStackYChanged) {
|
/**
|
||||||
|
* Add a listener when the StackY changes. The argument signifies whether an animation is
|
||||||
|
* needed.
|
||||||
|
*/
|
||||||
|
void setOnStackYChanged(Consumer<Boolean> onStackYChanged) {
|
||||||
mOnStackYChanged = onStackYChanged;
|
mOnStackYChanged = onStackYChanged;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1600,8 +1640,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
|
|||||||
protected void onConfigurationChanged(Configuration newConfig) {
|
protected void onConfigurationChanged(Configuration newConfig) {
|
||||||
super.onConfigurationChanged(newConfig);
|
super.onConfigurationChanged(newConfig);
|
||||||
Resources res = getResources();
|
Resources res = getResources();
|
||||||
mShouldUseSplitNotificationShade = shouldUseSplitNotificationShade(mFeatureFlags, res);
|
updateSplitNotificationShade();
|
||||||
updateUseRoundedRectClipping();
|
|
||||||
mStatusBarHeight = res.getDimensionPixelOffset(R.dimen.status_bar_height);
|
mStatusBarHeight = res.getDimensionPixelOffset(R.dimen.status_bar_height);
|
||||||
float densityScale = res.getDisplayMetrics().density;
|
float densityScale = res.getDisplayMetrics().density;
|
||||||
mSwipeHelper.setDensityScale(densityScale);
|
mSwipeHelper.setDensityScale(densityScale);
|
||||||
@@ -2528,8 +2567,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
|
|||||||
updateScrollStateForRemovedChild(child);
|
updateScrollStateForRemovedChild(child);
|
||||||
boolean animationGenerated = generateRemoveAnimation(child);
|
boolean animationGenerated = generateRemoveAnimation(child);
|
||||||
if (animationGenerated) {
|
if (animationGenerated) {
|
||||||
if (!mSwipedOutViews.contains(child)
|
if (!mSwipedOutViews.contains(child) || !isFullySwipedOut(child)) {
|
||||||
|| Math.abs(child.getTranslation()) != child.getWidth()) {
|
|
||||||
container.addTransientView(child, 0);
|
container.addTransientView(child, 0);
|
||||||
child.setTransientContainer(container);
|
child.setTransientContainer(container);
|
||||||
}
|
}
|
||||||
@@ -2541,6 +2579,13 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
|
|||||||
focusNextViewIfFocused(child);
|
focusNextViewIfFocused(child);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Has this view been fully swiped out such that it's not visible anymore.
|
||||||
|
*/
|
||||||
|
public boolean isFullySwipedOut(ExpandableView child) {
|
||||||
|
return Math.abs(child.getTranslation()) >= Math.abs(getTotalTranslationLength(child));
|
||||||
|
}
|
||||||
|
|
||||||
@ShadeViewRefactor(RefactorComponent.STATE_RESOLVER)
|
@ShadeViewRefactor(RefactorComponent.STATE_RESOLVER)
|
||||||
private void focusNextViewIfFocused(View view) {
|
private void focusNextViewIfFocused(View view) {
|
||||||
if (view instanceof ExpandableNotificationRow) {
|
if (view instanceof ExpandableNotificationRow) {
|
||||||
@@ -2660,17 +2705,27 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
|
|||||||
final int startingPosition = getPositionInLinearLayout(removedChild);
|
final int startingPosition = getPositionInLinearLayout(removedChild);
|
||||||
final int childHeight = getIntrinsicHeight(removedChild) + mPaddingBetweenElements;
|
final int childHeight = getIntrinsicHeight(removedChild) + mPaddingBetweenElements;
|
||||||
final int endPosition = startingPosition + childHeight;
|
final int endPosition = startingPosition + childHeight;
|
||||||
if (endPosition <= mOwnScrollY) {
|
final int scrollBoundaryStart = getScrollAmountToScrollBoundary();
|
||||||
|
mAnimateStackYForContentHeightChange = true;
|
||||||
|
// This is reset onLayout
|
||||||
|
if (endPosition <= mOwnScrollY - scrollBoundaryStart) {
|
||||||
// This child is fully scrolled of the top, so we have to deduct its height from the
|
// This child is fully scrolled of the top, so we have to deduct its height from the
|
||||||
// scrollPosition
|
// scrollPosition
|
||||||
setOwnScrollY(mOwnScrollY - childHeight);
|
setOwnScrollY(mOwnScrollY - childHeight);
|
||||||
} else if (startingPosition < mOwnScrollY) {
|
} else if (startingPosition < mOwnScrollY - scrollBoundaryStart) {
|
||||||
// This child is currently being scrolled into, set the scroll position to the
|
// This child is currently being scrolled into, set the scroll position to the
|
||||||
// start of this child
|
// start of this child
|
||||||
setOwnScrollY(startingPosition);
|
setOwnScrollY(startingPosition + scrollBoundaryStart);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the amount of scrolling needed to start clipping notifications.
|
||||||
|
*/
|
||||||
|
private int getScrollAmountToScrollBoundary() {
|
||||||
|
return mTopPadding - mQsScrollBoundaryPosition;
|
||||||
|
}
|
||||||
|
|
||||||
@ShadeViewRefactor(RefactorComponent.COORDINATOR)
|
@ShadeViewRefactor(RefactorComponent.COORDINATOR)
|
||||||
private int getIntrinsicHeight(View view) {
|
private int getIntrinsicHeight(View view) {
|
||||||
if (view instanceof ExpandableView) {
|
if (view instanceof ExpandableView) {
|
||||||
@@ -2759,7 +2814,10 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
|
|||||||
updateAnimationState(child);
|
updateAnimationState(child);
|
||||||
updateChronometerForChild(child);
|
updateChronometerForChild(child);
|
||||||
if (child instanceof ExpandableNotificationRow) {
|
if (child instanceof ExpandableNotificationRow) {
|
||||||
((ExpandableNotificationRow) child).setDismissRtl(mDismissRtl);
|
ExpandableNotificationRow row = (ExpandableNotificationRow) child;
|
||||||
|
row.setDismissRtl(mDismissRtl);
|
||||||
|
row.setDismissUsingRowTranslationX(mDismissUsingRowTranslationX);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3033,7 +3091,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
|
|||||||
removedTranslation = row.getTranslationWhenRemoved();
|
removedTranslation = row.getTranslationWhenRemoved();
|
||||||
ignoreChildren = false;
|
ignoreChildren = false;
|
||||||
}
|
}
|
||||||
childWasSwipedOut |= Math.abs(row.getTranslation()) == row.getWidth();
|
childWasSwipedOut |= isFullySwipedOut(row);
|
||||||
} else if (child instanceof MediaHeaderView) {
|
} else if (child instanceof MediaHeaderView) {
|
||||||
childWasSwipedOut = true;
|
childWasSwipedOut = true;
|
||||||
}
|
}
|
||||||
@@ -3041,11 +3099,11 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
|
|||||||
Rect clipBounds = child.getClipBounds();
|
Rect clipBounds = child.getClipBounds();
|
||||||
childWasSwipedOut = clipBounds != null && clipBounds.height() == 0;
|
childWasSwipedOut = clipBounds != null && clipBounds.height() == 0;
|
||||||
|
|
||||||
if (childWasSwipedOut && child instanceof ExpandableView) {
|
if (childWasSwipedOut) {
|
||||||
// Clean up any potential transient views if the child has already been swiped
|
// Clean up any potential transient views if the child has already been swiped
|
||||||
// out, as we won't be animating it further (due to its height already being
|
// out, as we won't be animating it further (due to its height already being
|
||||||
// clipped to 0.
|
// clipped to 0.
|
||||||
ViewGroup transientContainer = ((ExpandableView) child).getTransientContainer();
|
ViewGroup transientContainer = child.getTransientContainer();
|
||||||
if (transientContainer != null) {
|
if (transientContainer != null) {
|
||||||
transientContainer.removeTransientView(child);
|
transientContainer.removeTransientView(child);
|
||||||
}
|
}
|
||||||
@@ -3819,6 +3877,10 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
|
|||||||
}
|
}
|
||||||
|
|
||||||
void onChildHeightChanged(ExpandableView view, boolean needsAnimation) {
|
void onChildHeightChanged(ExpandableView view, boolean needsAnimation) {
|
||||||
|
boolean previouslyNeededAnimation = mAnimateStackYForContentHeightChange;
|
||||||
|
if (needsAnimation) {
|
||||||
|
mAnimateStackYForContentHeightChange = true;
|
||||||
|
}
|
||||||
updateContentHeight();
|
updateContentHeight();
|
||||||
updateScrollPositionOnExpandInBottom(view);
|
updateScrollPositionOnExpandInBottom(view);
|
||||||
clampScrollPosition();
|
clampScrollPosition();
|
||||||
@@ -3839,6 +3901,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
|
|||||||
requestAnimationOnViewResize(row);
|
requestAnimationOnViewResize(row);
|
||||||
}
|
}
|
||||||
requestChildrenUpdate();
|
requestChildrenUpdate();
|
||||||
|
mAnimateStackYForContentHeightChange = previouslyNeededAnimation;
|
||||||
}
|
}
|
||||||
|
|
||||||
void onChildHeightReset(ExpandableView view) {
|
void onChildHeightReset(ExpandableView view) {
|
||||||
@@ -4051,7 +4114,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
|
|||||||
expandableView.setFakeShadowIntensity(
|
expandableView.setFakeShadowIntensity(
|
||||||
diff / FakeShadowView.SHADOW_SIBLING_TRESHOLD,
|
diff / FakeShadowView.SHADOW_SIBLING_TRESHOLD,
|
||||||
previous.getOutlineAlpha(), (int) yLocation,
|
previous.getOutlineAlpha(), (int) yLocation,
|
||||||
previous.getOutlineTranslation());
|
(int) (previous.getOutlineTranslation() + previous.getTranslation()));
|
||||||
}
|
}
|
||||||
previous = expandableView;
|
previous = expandableView;
|
||||||
}
|
}
|
||||||
@@ -4564,13 +4627,18 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
|
|||||||
|
|
||||||
@ShadeViewRefactor(RefactorComponent.COORDINATOR)
|
@ShadeViewRefactor(RefactorComponent.COORDINATOR)
|
||||||
private void setOwnScrollY(int ownScrollY) {
|
private void setOwnScrollY(int ownScrollY) {
|
||||||
|
setOwnScrollY(ownScrollY, false /* animateScrollChangeListener */);
|
||||||
|
}
|
||||||
|
|
||||||
|
@ShadeViewRefactor(RefactorComponent.COORDINATOR)
|
||||||
|
private void setOwnScrollY(int ownScrollY, boolean animateStackYChangeListener) {
|
||||||
if (ownScrollY != mOwnScrollY) {
|
if (ownScrollY != mOwnScrollY) {
|
||||||
// We still want to call the normal scrolled changed for accessibility reasons
|
// We still want to call the normal scrolled changed for accessibility reasons
|
||||||
onScrollChanged(mScrollX, ownScrollY, mScrollX, mOwnScrollY);
|
onScrollChanged(mScrollX, ownScrollY, mScrollX, mOwnScrollY);
|
||||||
mOwnScrollY = ownScrollY;
|
mOwnScrollY = ownScrollY;
|
||||||
mAmbientState.setScrollY(mOwnScrollY);
|
mAmbientState.setScrollY(mOwnScrollY);
|
||||||
updateOnScrollChange();
|
updateOnScrollChange();
|
||||||
updateStackPosition();
|
updateStackPosition(animateStackYChangeListener);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -4636,6 +4704,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
|
|||||||
mStatusBarState = statusBarState;
|
mStatusBarState = statusBarState;
|
||||||
mAmbientState.setStatusBarState(statusBarState);
|
mAmbientState.setStatusBarState(statusBarState);
|
||||||
updateSpeedBumpIndex();
|
updateSpeedBumpIndex();
|
||||||
|
updateDismissBehavior();
|
||||||
}
|
}
|
||||||
|
|
||||||
void onStatePostChange(boolean fromShadeLocked) {
|
void onStatePostChange(boolean fromShadeLocked) {
|
||||||
@@ -5224,6 +5293,32 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void updateSplitNotificationShade() {
|
||||||
|
boolean split = shouldUseSplitNotificationShade(mFeatureFlags, getResources());
|
||||||
|
if (split != mShouldUseSplitNotificationShade) {
|
||||||
|
mShouldUseSplitNotificationShade = split;
|
||||||
|
updateDismissBehavior();
|
||||||
|
updateUseRoundedRectClipping();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateDismissBehavior() {
|
||||||
|
// On the split keyguard, dismissing with clipping without a visual boundary looks odd,
|
||||||
|
// so let's use the content dismiss behavior instead.
|
||||||
|
boolean dismissUsingRowTranslationX = !mShouldUseSplitNotificationShade
|
||||||
|
|| mStatusBarState != StatusBarState.KEYGUARD;
|
||||||
|
if (mDismissUsingRowTranslationX != dismissUsingRowTranslationX) {
|
||||||
|
mDismissUsingRowTranslationX = dismissUsingRowTranslationX;
|
||||||
|
for (int i = 0; i < getChildCount(); i++) {
|
||||||
|
View child = getChildAt(i);
|
||||||
|
if (child instanceof ExpandableNotificationRow) {
|
||||||
|
((ExpandableNotificationRow) child).setDismissUsingRowTranslationX(
|
||||||
|
dismissUsingRowTranslationX);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set if we're launching a notification right now.
|
* Set if we're launching a notification right now.
|
||||||
*/
|
*/
|
||||||
@@ -5258,6 +5353,19 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
|
|||||||
super.dispatchDraw(canvas);
|
super.dispatchDraw(canvas);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculate the total translation needed when dismissing.
|
||||||
|
*/
|
||||||
|
public float getTotalTranslationLength(View animView) {
|
||||||
|
if (!mDismissUsingRowTranslationX) {
|
||||||
|
return animView.getMeasuredWidth();
|
||||||
|
}
|
||||||
|
float notificationWidth = animView.getMeasuredWidth();
|
||||||
|
int containerWidth = getMeasuredWidth();
|
||||||
|
float padding = (containerWidth - notificationWidth) / 2.0f;
|
||||||
|
return containerWidth - padding;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A listener that is notified when the empty space below the notifications is clicked on
|
* A listener that is notified when the empty space below the notifications is clicked on
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -383,6 +383,11 @@ public class NotificationStackScrollLayoutController {
|
|||||||
false /* resetMenu */);
|
false /* resetMenu */);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public float getTotalTranslationLength(View animView) {
|
||||||
|
return mView.getTotalTranslationLength(animView);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onSnooze(StatusBarNotification sbn,
|
public void onSnooze(StatusBarNotification sbn,
|
||||||
NotificationSwipeActionHelper.SnoozeOption snoozeOption) {
|
NotificationSwipeActionHelper.SnoozeOption snoozeOption) {
|
||||||
@@ -1018,7 +1023,7 @@ public class NotificationStackScrollLayoutController {
|
|||||||
mView.setQsExpansionFraction(expansionFraction);
|
mView.setQsExpansionFraction(expansionFraction);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setOnStackYChanged(Runnable onStackYChanged) {
|
public void setOnStackYChanged(Consumer<Boolean> onStackYChanged) {
|
||||||
mView.setOnStackYChanged(onStackYChanged);
|
mView.setOnStackYChanged(onStackYChanged);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -324,6 +324,11 @@ class NotificationSwipeHelper extends SwipeHelper implements NotificationSwipeAc
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected float getTotalTranslationLength(View animView) {
|
||||||
|
return mCallback.getTotalTranslationLength(animView);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setTranslation(View v, float translate) {
|
public void setTranslation(View v, float translate) {
|
||||||
if (v instanceof SwipeableView) {
|
if (v instanceof SwipeableView) {
|
||||||
@@ -466,6 +471,13 @@ class NotificationSwipeHelper extends SwipeHelper implements NotificationSwipeAc
|
|||||||
void onSnooze(StatusBarNotification sbn, SnoozeOption snoozeOption);
|
void onSnooze(StatusBarNotification sbn, SnoozeOption snoozeOption);
|
||||||
|
|
||||||
void onDismiss();
|
void onDismiss();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the total translation length where we want to swipe to when dismissing the view. By
|
||||||
|
* default this is the size of the view, but can also be larger.
|
||||||
|
* @param animView the view to ask about
|
||||||
|
*/
|
||||||
|
float getTotalTranslationLength(View animView);
|
||||||
}
|
}
|
||||||
|
|
||||||
static class Builder {
|
static class Builder {
|
||||||
|
|||||||
@@ -392,7 +392,7 @@ public class StackStateAnimator {
|
|||||||
0, () -> removeTransientView(changingView), null);
|
0, () -> removeTransientView(changingView), null);
|
||||||
} else if (event.animationType ==
|
} else if (event.animationType ==
|
||||||
NotificationStackScrollLayout.AnimationEvent.ANIMATION_TYPE_REMOVE_SWIPED_OUT) {
|
NotificationStackScrollLayout.AnimationEvent.ANIMATION_TYPE_REMOVE_SWIPED_OUT) {
|
||||||
if (Math.abs(changingView.getTranslation()) == changingView.getWidth()
|
if (mHostLayout.isFullySwipedOut(changingView)
|
||||||
&& changingView.getTransientContainer() != null) {
|
&& changingView.getTransientContainer() != null) {
|
||||||
changingView.getTransientContainer().removeTransientView(changingView);
|
changingView.getTransientContainer().removeTransientView(changingView);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -832,6 +832,7 @@ public class NotificationPanelViewController extends PanelViewController {
|
|||||||
mNotificationStackScrollLayoutController.setOverscrollTopChangedListener(
|
mNotificationStackScrollLayoutController.setOverscrollTopChangedListener(
|
||||||
mOnOverscrollTopChangedListener);
|
mOnOverscrollTopChangedListener);
|
||||||
mNotificationStackScrollLayoutController.setOnScrollListener(this::onNotificationScrolled);
|
mNotificationStackScrollLayoutController.setOnScrollListener(this::onNotificationScrolled);
|
||||||
|
mNotificationStackScrollLayoutController.setOnStackYChanged(this::onStackYChanged);
|
||||||
mNotificationStackScrollLayoutController.setOnEmptySpaceClickListener(
|
mNotificationStackScrollLayoutController.setOnEmptySpaceClickListener(
|
||||||
mOnEmptySpaceClickListener);
|
mOnEmptySpaceClickListener);
|
||||||
addTrackingHeadsUpListener(mNotificationStackScrollLayoutController::setTrackingHeadsUp);
|
addTrackingHeadsUpListener(mNotificationStackScrollLayoutController::setTrackingHeadsUp);
|
||||||
@@ -2211,15 +2212,17 @@ public class NotificationPanelViewController extends PanelViewController {
|
|||||||
mDepthController.setQsPanelExpansion(qsExpansionFraction);
|
mDepthController.setQsPanelExpansion(qsExpansionFraction);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Runnable mOnStackYChanged = () -> {
|
private void onStackYChanged(boolean shouldAnimate) {
|
||||||
if (mQs != null) {
|
if (mQs != null) {
|
||||||
|
if (shouldAnimate) {
|
||||||
|
mAnimateNextNotificationBounds = true;
|
||||||
|
mNotificationBoundsAnimationDelay = 0;
|
||||||
|
}
|
||||||
setQSClippingBounds();
|
setQSClippingBounds();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
private void onNotificationScrolled(int newScrollPosition) {
|
private void onNotificationScrolled(int newScrollPosition) {
|
||||||
// Since this is an overscroller, sometimes the scrollY can be temporarily negative
|
|
||||||
// (when overscrollng on the top and flinging). Let's
|
|
||||||
updateQSExpansionEnabledAmbient();
|
updateQSExpansionEnabledAmbient();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3348,7 +3351,6 @@ public class NotificationPanelViewController extends PanelViewController {
|
|||||||
// The expandedHeight is always the full panel Height when bypassing
|
// The expandedHeight is always the full panel Height when bypassing
|
||||||
expandedHeight = getMaxPanelHeightNonBypass();
|
expandedHeight = getMaxPanelHeightNonBypass();
|
||||||
}
|
}
|
||||||
mNotificationStackScrollLayoutController.setOnStackYChanged(mOnStackYChanged);
|
|
||||||
mNotificationStackScrollLayoutController.setExpandedHeight(expandedHeight);
|
mNotificationStackScrollLayoutController.setExpandedHeight(expandedHeight);
|
||||||
updateKeyguardBottomAreaAlpha();
|
updateKeyguardBottomAreaAlpha();
|
||||||
updateBigClockAlpha();
|
updateBigClockAlpha();
|
||||||
|
|||||||
@@ -289,6 +289,7 @@ public class ExpandableNotificationRowTest extends SysuiTestCase {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testIconScrollXAfterTranslationAndReset() throws Exception {
|
public void testIconScrollXAfterTranslationAndReset() throws Exception {
|
||||||
|
mGroupRow.setDismissUsingRowTranslationX(false);
|
||||||
mGroupRow.setTranslation(50);
|
mGroupRow.setTranslation(50);
|
||||||
assertEquals(50, -mGroupRow.getEntry().getIcons().getShelfIcon().getScrollX());
|
assertEquals(50, -mGroupRow.getEntry().getIcons().getShelfIcon().getScrollX());
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user