Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 47c85a35 authored by Jorim Jaggi's avatar Jorim Jaggi
Browse files

Fix PanelView over expanding behavior.

Fixes a bug that the panel height was wrongly calculated and lagging
one frame behind. Also fixes the animation when overscrolling and
then flinging the panel to collapse. In addition, the logic to handle
the over expanding is much cleaner and calculated in an absolut
manner (before, it was relative an really complicated to understand).

Bug: 14487435
Change-Id: If8dbb3e063ef63f51f6dac0ae5bf276480514103
parent 7256a852
Loading
Loading
Loading
Loading
+24 −9
Original line number Diff line number Diff line
@@ -48,7 +48,6 @@ public class NotificationPanelView extends PanelView implements
        View.OnClickListener, NotificationStackScrollLayout.OnOverscrollTopChangedListener,
        KeyguardPageSwipeHelper.Callback {

    private static final float EXPANSION_RUBBER_BAND_EXTRA_FACTOR = 0.6f;
    private static final float LOCK_ICON_ACTIVE_SCALE = 1.2f;

    private KeyguardPageSwipeHelper mPageSwiper;
@@ -719,6 +718,16 @@ public class NotificationPanelView extends PanelView implements
        updateUnlockIcon();
    }

    @Override
    protected float getOverExpansionAmount() {
        return mNotificationStackScroller.getCurrentOverScrollAmount(true /* top */);
    }

    @Override
    protected float getOverExpansionPixels() {
        return mNotificationStackScroller.getCurrentOverScrolledPixels(true /* top */);
    }

    private void updateUnlockIcon() {
        if (mStatusBar.getBarState() == StatusBarState.KEYGUARD
                || mStatusBar.getBarState() == StatusBarState.SHADE_LOCKED) {
@@ -805,14 +814,17 @@ public class NotificationPanelView extends PanelView implements
    }

    @Override
    protected void onOverExpansionChanged(float overExpansion) {
    protected void setOverExpansion(float overExpansion, boolean isPixels) {
        if (mStatusBar.getBarState() != StatusBarState.KEYGUARD) {
            float currentOverScroll = mNotificationStackScroller.getCurrentOverScrolledPixels(true);
            float expansionChange = overExpansion - mOverExpansion;
            expansionChange *= EXPANSION_RUBBER_BAND_EXTRA_FACTOR;
            mNotificationStackScroller.setOverScrolledPixels(currentOverScroll + expansionChange,
                    true /* onTop */,
                    false /* animate */);
            mNotificationStackScroller.setOnHeightChangedListener(null);
            if (isPixels) {
                mNotificationStackScroller.setOverScrolledPixels(
                        overExpansion, true /* onTop */, false /* animate */);
            } else {
                mNotificationStackScroller.setOverScrollAmount(
                        overExpansion, true /* onTop */, false /* animate */);
            }
            mNotificationStackScroller.setOnHeightChangedListener(this);
        }
    }

@@ -828,7 +840,10 @@ public class NotificationPanelView extends PanelView implements
    @Override
    protected void onTrackingStopped(boolean expand) {
        super.onTrackingStopped(expand);
        mNotificationStackScroller.setOverScrolledPixels(0.0f, true /* onTop */, true /* animate */);
        if (expand) {
            mNotificationStackScroller.setOverScrolledPixels(
                    0.0f, true /* onTop */, true /* animate */);
        }
        if (expand && (mStatusBar.getBarState() == StatusBarState.KEYGUARD
                || mStatusBar.getBarState() == StatusBarState.SHADE_LOCKED)) {
            mPageSwiper.showAllIcons(true);
+28 −21
Original line number Diff line number Diff line
@@ -41,7 +41,6 @@ import java.io.PrintWriter;
public abstract class PanelView extends FrameLayout {
    public static final boolean DEBUG = PanelBar.DEBUG;
    public static final String TAG = PanelView.class.getSimpleName();
    protected float mOverExpansion;

    private final void logf(String fmt, Object... args) {
        Log.v(TAG, (mViewName != null ? (mViewName + ": ") : "") + String.format(fmt, args));
@@ -61,6 +60,7 @@ public abstract class PanelView extends FrameLayout {
    private int mTrackingPointer;
    protected int mTouchSlop;
    protected boolean mHintAnimationRunning;
    private boolean mOverExpandedBeforeFling;

    private ValueAnimator mHeightAnimator;
    private ObjectAnimator mPeekAnimator;
@@ -370,13 +370,12 @@ public abstract class PanelView extends FrameLayout {
    protected void fling(float vel, boolean expand) {
        cancelPeek();
        float target = expand ? getMaxPanelHeight() : 0.0f;
        if (target == mExpandedHeight || mOverExpansion > 0) {
        if (target == mExpandedHeight || getOverExpansionAmount() > 0f && expand) {
            onExpandingFinished();
            mExpandedHeight = target;
            mOverExpansion = 0.0f;
            mBar.panelExpansionChanged(this, mExpandedFraction);
            return;
        }
        mOverExpandedBeforeFling = getOverExpansionAmount() > 0f;
        ValueAnimator animator = createHeightAnimator(target);
        if (expand) {
            mFlingAnimationUtils.apply(animator, mExpandedHeight, target, vel, getHeight());
@@ -396,8 +395,8 @@ public abstract class PanelView extends FrameLayout {
                onExpandingFinished();
            }
        });
        animator.start();
        mHeightAnimator = animator;
        animator.start();
    }

    @Override
@@ -433,7 +432,7 @@ public abstract class PanelView extends FrameLayout {

    public void setExpandedHeight(float height) {
        if (DEBUG) logf("setExpandedHeight(%.1f)", height);
        setExpandedHeightInternal(height);
        setExpandedHeightInternal(height + getOverExpansionPixels());
        mBar.panelExpansionChanged(PanelView.this, mExpandedFraction);
    }

@@ -451,32 +450,39 @@ public abstract class PanelView extends FrameLayout {
        // If the user isn't actively poking us, let's update the height
        if (!mTracking && mHeightAnimator == null
                && mExpandedHeight > 0 && currentMaxPanelHeight != mExpandedHeight) {
            setExpandedHeightInternal(currentMaxPanelHeight);
            setExpandedHeight(currentMaxPanelHeight);
        }
    }

    public void setExpandedHeightInternal(float h) {
        float fh = getMaxPanelHeight();
        mExpandedHeight = Math.max(0, Math.min(fh, h));
        float overExpansion = h - fh;
        overExpansion = Math.max(0, overExpansion);
        if (overExpansion != mOverExpansion) {
            onOverExpansionChanged(overExpansion);
            mOverExpansion = overExpansion;
        float fhWithoutOverExpansion = getMaxPanelHeight() - getOverExpansionAmount();
        if (mHeightAnimator == null) {
            float overExpansionPixels = Math.max(0, h - fhWithoutOverExpansion);
            if (getOverExpansionPixels() != overExpansionPixels && mTracking) {
                setOverExpansion(overExpansionPixels, true /* isPixels */);
            }
            mExpandedHeight = Math.min(h, fhWithoutOverExpansion) + getOverExpansionAmount();
        } else {
            mExpandedHeight = h;
            if (mOverExpandedBeforeFling) {
                setOverExpansion(Math.max(0, h - fhWithoutOverExpansion), false /* isPixels */);
            }

        if (DEBUG) {
            logf("setExpansion: height=%.1f fh=%.1f tracking=%s", h, fh, mTracking ? "T" : "f");
        }

        onHeightUpdated(mExpandedHeight);
        mExpandedFraction = Math.min(1f, (fh == 0) ? 0 : mExpandedHeight / fh);
        mExpandedFraction = Math.min(1f, fhWithoutOverExpansion == 0
                ? 0
                : mExpandedHeight / fhWithoutOverExpansion);
    }

    protected abstract void onOverExpansionChanged(float overExpansion);
    protected abstract void setOverExpansion(float overExpansion, boolean isPixels);

    protected abstract void onHeightUpdated(float expandedHeight);

    protected abstract float getOverExpansionAmount();

    protected abstract float getOverExpansionPixels();

    /**
     * This returns the maximum height of the panel. Children should override this if their
     * desired height is not the full height.
@@ -624,7 +630,8 @@ public abstract class PanelView extends FrameLayout {
        animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                setExpandedHeight((Float) animation.getAnimatedValue());
                setExpandedHeightInternal((Float) animation.getAnimatedValue());
                mBar.panelExpansionChanged(PanelView.this, mExpandedFraction);
            }
        });
        return animator;
+9 −5
Original line number Diff line number Diff line
@@ -52,6 +52,7 @@ public class NotificationStackScrollLayout extends ViewGroup
    private static final boolean DEBUG = false;
    private static final float RUBBER_BAND_FACTOR_NORMAL = 0.35f;
    private static final float RUBBER_BAND_FACTOR_AFTER_EXPAND = 0.15f;
    private static final float RUBBER_BAND_FACTOR_ON_PANEL_EXPAND = 0.21f;

    /**
     * Sentinel value for no current active pointer. Used by {@link #mActivePointerId}.
@@ -1267,11 +1268,14 @@ public class NotificationStackScrollLayout extends ViewGroup
    }

    private float getRubberBandFactor() {
        return mExpandedInThisMotion
                ? RUBBER_BAND_FACTOR_AFTER_EXPAND
                : (mScrolledToTopOnFirstDown
                    ? 1.0f
                    : RUBBER_BAND_FACTOR_NORMAL);
        if (mExpandedInThisMotion) {
            return RUBBER_BAND_FACTOR_AFTER_EXPAND;
        } else if (mIsExpansionChanging) {
            return RUBBER_BAND_FACTOR_ON_PANEL_EXPAND;
        } else if (mScrolledToTopOnFirstDown) {
            return 1.0f;
        }
        return RUBBER_BAND_FACTOR_NORMAL;
    }

    private void endDrag() {
+12 −2
Original line number Diff line number Diff line
@@ -726,11 +726,21 @@ public class StackStateAnimator {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                float currentOverScroll = (float) animation.getAnimatedValue();
                mHostLayout.setOverScrollAmount(currentOverScroll, onTop, false /* animate */,
                        false /* cancelAnimators */);
                mHostLayout.setOverScrollAmount(
                        currentOverScroll, onTop, false /* animate */, false /* cancelAnimators */);
            }
        });
        overScrollAnimator.setInterpolator(mFastOutSlowInInterpolator);
        overScrollAnimator.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationEnd(Animator animation) {
                if (onTop) {
                    mTopOverScrollAnimator = null;
                } else {
                    mBottomOverScrollAnimator = null;
                }
            }
        });
        overScrollAnimator.start();
        if (onTop) {
            mTopOverScrollAnimator = overScrollAnimator;