Start expanding QS directly when overscrolling to it.
This removes the janky transition from scrolling to flinging.
Change-Id: I691ac94ec06af7f7431ad162e07c21d2c753e99c
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
index c82bdf6..2790540 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
@@ -94,6 +94,7 @@
private int mQsMaxExpansionHeight;
private int mQsPeekHeight;
private boolean mStackScrollerOverscrolling;
+ private boolean mQsExpansionFromOverscroll;
private boolean mQsExpansionEnabled = true;
private ValueAnimator mQsExpansionAnimator;
private FlingAnimationUtils mFlingAnimationUtils;
@@ -523,19 +524,25 @@
@Override
- public void onOverscrollTopChanged(float amount) {
+ public void onOverscrollTopChanged(float amount, boolean isRubberbanded) {
cancelAnimation();
float rounded = amount >= 1f ? amount : 0f;
- mStackScrollerOverscrolling = rounded != 0f;
+ mStackScrollerOverscrolling = rounded != 0f && isRubberbanded;
+ mQsExpansionFromOverscroll = rounded != 0f;
setQsExpansion(mQsMinExpansionHeight + rounded);
updateQsState();
}
@Override
public void flingTopOverscroll(float velocity, boolean open) {
- mStackScrollerOverscrolling = false;
setQsExpansion(mQsExpansionHeight);
- flingSettings(velocity, open);
+ flingSettings(velocity, open, new Runnable() {
+ @Override
+ public void run() {
+ mStackScrollerOverscrolling = false;
+ mQsExpansionFromOverscroll = false;
+ }
+ });
}
private void onQsExpansionStarted() {
@@ -571,13 +578,12 @@
private void updateQsState() {
boolean expandVisually = mQsExpanded || mStackScrollerOverscrolling;
mHeader.setExpanded(expandVisually, mStackScrollerOverscrolling);
- mNotificationStackScroller.setEnabled(!mQsExpanded);
+ mNotificationStackScroller.setEnabled(!mQsExpanded || mQsExpansionFromOverscroll);
mQsPanel.setVisibility(expandVisually ? View.VISIBLE : View.INVISIBLE);
- mQsContainer.setVisibility(mKeyguardShowing && !expandVisually
- ? View.INVISIBLE
- : View.VISIBLE);
+ mQsContainer.setVisibility(
+ mKeyguardShowing && !expandVisually ? View.INVISIBLE : View.VISIBLE);
mScrollView.setTouchEnabled(mQsExpanded);
- mNotificationStackScroller.setTouchEnabled(!mQsExpanded);
+ mNotificationStackScroller.setTouchEnabled(!mQsExpanded || mQsExpansionFromOverscroll);
}
private void setQsExpansion(float height) {
@@ -640,9 +646,17 @@
mQsExpansionAnimator.cancel();
}
}
+
private void flingSettings(float vel, boolean expand) {
+ flingSettings(vel, expand, null);
+ }
+
+ private void flingSettings(float vel, boolean expand, final Runnable onFinishRunnable) {
float target = expand ? mQsMaxExpansionHeight : mQsMinExpansionHeight;
if (target == mQsExpansionHeight) {
+ if (onFinishRunnable != null) {
+ onFinishRunnable.run();
+ }
return;
}
ValueAnimator animator = ValueAnimator.ofFloat(mQsExpansionHeight, target);
@@ -657,6 +671,9 @@
@Override
public void onAnimationEnd(Animator animation) {
mQsExpansionAnimator = null;
+ if (onFinishRunnable != null) {
+ onFinishRunnable.run();
+ }
}
});
animator.start();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
index c9a1b28..94fdd1f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
@@ -988,34 +988,50 @@
*/
public void setOverScrollAmount(float amount, boolean onTop, boolean animate,
boolean cancelAnimators) {
+ setOverScrollAmount(amount, onTop, animate, cancelAnimators, isRubberbanded(onTop));
+ }
+
+ /**
+ * Set the effective overScroll amount which will be directly reflected in the layout.
+ *
+ * @param amount The amount to overScroll by.
+ * @param onTop Should the effect be applied on top of the scroller.
+ * @param animate Should an animation be performed.
+ * @param cancelAnimators Should running animations be cancelled.
+ * @param isRubberbanded The value which will be passed to
+ * {@link OnOverscrollTopChangedListener#onOverscrollTopChanged}
+ */
+ public void setOverScrollAmount(float amount, boolean onTop, boolean animate,
+ boolean cancelAnimators, boolean isRubberbanded) {
if (cancelAnimators) {
mStateAnimator.cancelOverScrollAnimators(onTop);
}
- setOverScrollAmountInternal(amount, onTop, animate);
+ setOverScrollAmountInternal(amount, onTop, animate, isRubberbanded);
}
- private void setOverScrollAmountInternal(float amount, boolean onTop, boolean animate) {
+ private void setOverScrollAmountInternal(float amount, boolean onTop, boolean animate,
+ boolean isRubberbanded) {
amount = Math.max(0, amount);
if (animate) {
- mStateAnimator.animateOverScrollToAmount(amount, onTop);
+ mStateAnimator.animateOverScrollToAmount(amount, onTop, isRubberbanded);
} else {
setOverScrolledPixels(amount / getRubberBandFactor(onTop), onTop);
mAmbientState.setOverScrollAmount(amount, onTop);
if (onTop) {
- notifyOverscrollTopListener(amount);
+ notifyOverscrollTopListener(amount, isRubberbanded);
}
requestChildrenUpdate();
}
}
- private void notifyOverscrollTopListener(float amount) {
+ private void notifyOverscrollTopListener(float amount, boolean isRubberbanded) {
mExpandHelper.onlyObserveMovements(amount > 1.0f);
if (mDontReportNextOverScroll) {
mDontReportNextOverScroll = false;
return;
}
if (mOverscrollTopChangedListener != null) {
- mOverscrollTopChangedListener.onOverscrollTopChanged(amount);
+ mOverscrollTopChangedListener.onOverscrollTopChanged(amount, isRubberbanded);
}
}
@@ -1061,9 +1077,9 @@
updateChildren();
float overScrollTop = getCurrentOverScrollAmount(true);
if (mOwnScrollY < 0) {
- notifyOverscrollTopListener(-mOwnScrollY);
+ notifyOverscrollTopListener(-mOwnScrollY, isRubberbanded(true));
} else {
- notifyOverscrollTopListener(overScrollTop);
+ notifyOverscrollTopListener(overScrollTop, isRubberbanded(true));
}
}
} else {
@@ -1288,6 +1304,16 @@
return RUBBER_BAND_FACTOR_NORMAL;
}
+ /**
+ * Accompanying function for {@link #getRubberBandFactor}: Returns true if the overscroll is
+ * rubberbanded, false if it is technically an overscroll but rather a motion to expand the
+ * overscroll view (e.g. expand QS).
+ */
+ private boolean isRubberbanded(boolean onTop) {
+ return !onTop || mExpandedInThisMotion || mIsExpansionChanging
+ || !mScrolledToTopOnFirstDown;
+ }
+
private void endDrag() {
setIsBeingDragged(false);
@@ -1880,7 +1906,16 @@
* A listener that gets notified when the overscroll at the top has changed.
*/
public interface OnOverscrollTopChangedListener {
- public void onOverscrollTopChanged(float amount);
+
+ /**
+ * Notifies a listener that the overscroll has changed.
+ *
+ * @param amount the amount of overscroll, in pixels
+ * @param isRubberbanded if true, this is a rubberbanded overscroll; if false, this is an
+ * unrubberbanded motion to directly expand overscroll view (e.g expand
+ * QS)
+ */
+ public void onOverscrollTopChanged(float amount, boolean isRubberbanded);
/**
* Notify a listener that the scroller wants to escape from the scrolling motion and
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackStateAnimator.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackStateAnimator.java
index 5efbc99..fb54905 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackStateAnimator.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackStateAnimator.java
@@ -719,7 +719,8 @@
}
}
- public void animateOverScrollToAmount(float targetAmount, final boolean onTop) {
+ public void animateOverScrollToAmount(float targetAmount, final boolean onTop,
+ final boolean isRubberbanded) {
final float startOverScrollAmount = mHostLayout.getCurrentOverScrollAmount(onTop);
if (targetAmount == startOverScrollAmount) {
return;
@@ -733,7 +734,8 @@
public void onAnimationUpdate(ValueAnimator animation) {
float currentOverScroll = (float) animation.getAnimatedValue();
mHostLayout.setOverScrollAmount(
- currentOverScroll, onTop, false /* animate */, false /* cancelAnimators */);
+ currentOverScroll, onTop, false /* animate */, false /* cancelAnimators */,
+ isRubberbanded);
}
});
overScrollAnimator.setInterpolator(mFastOutSlowInInterpolator);