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

Commit 343e6e25 authored by Selim Cinek's avatar Selim Cinek
Browse files

Avoiding intermediate states in NotificationStackScroller

The StackScrollAlgorithm was modified such that the notifications
now don't layout anymore during scrolling and therefore
intermediate states are avoided except for the first card.
Also made the top stack a bit smaller and fixed a bug where the
scrolling was not working on the very first try.

Bug: 14080821
Bug: 14081652
Change-Id: I924a9f8532486856fc2ecd88f6c10d26023a5bc3
parent 6513f35c
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -250,7 +250,7 @@
    <dimen name="notification_stack_margin_bottom">0dp</dimen>

    <!-- Space reserved for the cards behind the top card in the top stack -->
    <dimen name="top_stack_peek_amount">24dp</dimen>
    <dimen name="top_stack_peek_amount">12dp</dimen>

    <!-- Space reserved for the cards behind the top card in the bottom stack -->
    <dimen name="bottom_stack_peek_amount">18dp</dimen>
+8 −1
Original line number Diff line number Diff line
@@ -195,6 +195,12 @@ public class ExpandHelper implements Gefingerpoken, OnClickListener {
        mGravity = Gravity.TOP;
        mScaleAnimation = ObjectAnimator.ofFloat(mScaler, "height", 0f);
        mScaleAnimation.setDuration(EXPAND_DURATION);
        mScaleAnimation.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationEnd(Animator animation) {
                mCallback.setUserLockedChild(mCurrView, false);
            }
        });
        mPopLimit = mContext.getResources().getDimension(R.dimen.blinds_pop_threshold);
        mPopDuration = mContext.getResources().getInteger(R.integer.blinds_pop_duration_ms);
        mPullGestureMinXSpan = mContext.getResources().getDimension(R.dimen.pull_span_min);
@@ -549,8 +555,9 @@ public class ExpandHelper implements Gefingerpoken, OnClickListener {
            mScaleAnimation.setFloatValues(targetHeight);
            mScaleAnimation.setupStartValues();
            mScaleAnimation.start();
        }
        } else {
            mCallback.setUserLockedChild(mCurrView, false);
        }

        mExpanding = false;
        mExpansionStyle = NONE;
+21 −0
Original line number Diff line number Diff line
@@ -54,6 +54,7 @@ public class ExpandableNotificationRow extends FrameLayout
    private boolean mMaxHeightNeedsUpdate;
    private NotificationActivator mActivator;
    private LatestItemView.OnActivatedListener mOnActivatedListener;
    private boolean mSelfInitiatedLayout;

    public ExpandableNotificationRow(Context context, AttributeSet attrs) {
        super(context, attrs);
@@ -162,6 +163,11 @@ public class ExpandableNotificationRow extends FrameLayout
    }

    private void updateMaxExpandHeight() {

        // We don't want this method to trigger a layout of the whole view hierarchy,
        // as the layout parameters in the end are the same which they were in the beginning.
        // Otherwise a loop may occur if this method is called on the layout of a parent.
        mSelfInitiatedLayout = true;
        ViewGroup.LayoutParams lp = getLayoutParams();
        int oldHeight = lp.height;
        lp.height = ViewGroup.LayoutParams.WRAP_CONTENT;
@@ -171,6 +177,14 @@ public class ExpandableNotificationRow extends FrameLayout
        lp.height = oldHeight;
        setLayoutParams(lp);
        mMaxExpandHeight = getMeasuredHeight();
        mSelfInitiatedLayout = false;
    }

    @Override
    public void requestLayout() {
        if (!mSelfInitiatedLayout) {
            super.requestLayout();
        }
    }

    /**
@@ -257,4 +271,11 @@ public class ExpandableNotificationRow extends FrameLayout
    public void setBackgroundResourceIds(int bgResId, int dimmedBgResId) {
        mLatestItemView.setBackgroundResourceIds(bgResId, dimmedBgResId);
    }

    /**
     * @return the potential height this view could expand in addition.
     */
    public int getExpandPotential() {
        return getMaximumAllowedExpandHeight() - getHeight();
    }
}
+50 −41
Original line number Diff line number Diff line
@@ -20,7 +20,6 @@ import android.content.Context;
import android.content.res.Configuration;

import android.graphics.Canvas;
import android.graphics.Outline;
import android.graphics.Paint;

import android.util.AttributeSet;
@@ -31,6 +30,7 @@ import android.view.VelocityTracker;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.ViewGroup;
import android.view.ViewTreeObserver;
import android.widget.OverScroller;

import com.android.systemui.ExpandHelper;
@@ -55,7 +55,7 @@ public class NotificationStackScrollLayout extends ViewGroup
    private static final int INVALID_POINTER = -1;

    private SwipeHelper mSwipeHelper;
    private boolean mSwipingInProgress = true;
    private boolean mSwipingInProgress;
    private int mCurrentStackHeight = Integer.MAX_VALUE;
    private int mOwnScrollY;
    private int mMaxLayoutHeight;
@@ -73,7 +73,6 @@ public class NotificationStackScrollLayout extends ViewGroup

    private int mSidePaddings;
    private Paint mDebugPaint;
    private int mBackgroundRoundedRectCornerRadius;
    private int mContentHeight;
    private int mCollapsedSize;
    private int mBottomStackPeekSize;
@@ -145,9 +144,6 @@ public class NotificationStackScrollLayout extends ViewGroup

        mSidePaddings = context.getResources()
                .getDimensionPixelSize(R.dimen.notification_side_padding);
        mBackgroundRoundedRectCornerRadius = context.getResources()
                .getDimensionPixelSize(
                        com.android.internal.R.dimen.notification_quantum_rounded_rect_radius);
        mCollapsedSize = context.getResources()
                .getDimensionPixelSize(R.dimen.notification_row_min_height);
        mBottomStackPeekSize = context.getResources()
@@ -177,18 +173,23 @@ public class NotificationStackScrollLayout extends ViewGroup
            View child = getChildAt(i);
            float width = child.getMeasuredWidth();
            float height = child.getMeasuredHeight();
            int oldWidth = child.getWidth();
            int oldHeight = child.getHeight();
            child.layout((int) (centerX - width / 2.0f),
                    0,
                    (int) (centerX + width / 2.0f),
                    (int) height);
            updateChildOutline(child, width, height, oldWidth, oldHeight);
        }
        setMaxLayoutHeight(getHeight() - mEmptyMarginBottom);
        updateContentHeight();
        getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
            @Override
            public boolean onPreDraw() {
                updateScrollPositionIfNecessary();
                updateChildren();
        updateContentHeight();
                getViewTreeObserver().removeOnPreDrawListener(this);
                return true;
            }
        });

    }

    public void setChildLocationsChangedListener(OnChildLocationsChangedListener listener) {
@@ -227,7 +228,6 @@ public class NotificationStackScrollLayout extends ViewGroup
            mCurrentStackScrollState.setScrollY(mOwnScrollY);
            mStackScrollAlgorithm.getStackScrollState(mCurrentStackScrollState);
            mCurrentStackScrollState.apply();
            mOwnScrollY = mCurrentStackScrollState.getScrollY();
            if (mListener != null) {
                mListener.onChildLocationsChanged(this);
            }
@@ -240,31 +240,6 @@ public class NotificationStackScrollLayout extends ViewGroup
        return false;
    }

    private void updateChildOutline(View child,
                                    float width,
                                    float height,
                                    int oldWidth,
                                    int oldHeight) {
        // The children currently have paddings inside themselfs because of the expansion
        // visualization. In order for the shadows to work correctly we have to set the correct
        // outline.
        View container = child.findViewById(R.id.container);
        if (container != null && (oldWidth != width || oldHeight != height)) {
            Outline outline = getOutlineForSize(container.getLeft(),
                    container.getTop(),
                    container.getWidth(),
                    container.getHeight());
            child.setOutline(outline);
        }
    }

    private Outline getOutlineForSize(int leftInset, int topInset, int width, int height) {
        Outline result = new Outline();
        result.setRoundRect(leftInset, topInset, leftInset + width, topInset + height,
                mBackgroundRoundedRectCornerRadius);
        return result;
    }

    private void updateScrollPositionIfNecessary() {
        int scrollRange = getScrollRange();
        if (scrollRange < mOwnScrollY) {
@@ -284,7 +259,7 @@ public class NotificationStackScrollLayout extends ViewGroup
     *
     * @return either the layout height or the externally defined height, whichever is smaller
     */
    private float getLayoutHeight() {
    private int getLayoutHeight() {
        return Math.min(mMaxLayoutHeight, mCurrentStackHeight);
    }

@@ -640,14 +615,48 @@ public class NotificationStackScrollLayout extends ViewGroup

    private int getScrollRange() {
        int scrollRange = 0;
        if (getChildCount() > 0) {
        View firstChild = getFirstChildNotGone();
        if (firstChild != null) {
            int contentHeight = getContentHeight();
            scrollRange = Math.max(0,
                    contentHeight - mMaxLayoutHeight + mBottomStackPeekSize);
            int firstChildMaxExpandHeight = getMaxExpandHeight(firstChild);
            int firstChildExpandPotential = firstChildMaxExpandHeight - firstChild.getHeight();

            // If we already scrolled in, the first child is layouted smaller than it actually
            // could be when expanded. We have to compensate for this loss of the contentHeight
            // by adding the expand potential again.
            contentHeight += firstChildExpandPotential;
            scrollRange = Math.max(0, contentHeight - mMaxLayoutHeight + mBottomStackPeekSize);
            if (scrollRange > 0 && getChildCount() > 0) {
                // We want to at least be able collapse the first item and not ending in a weird
                // end state.
                scrollRange = Math.max(scrollRange, firstChildMaxExpandHeight - mCollapsedSize);
            }
        }
        return scrollRange;
    }

    /**
     * @return the first child which has visibility unequal to GONE
     */
    private View getFirstChildNotGone() {
        int childCount = getChildCount();
        for (int i = 0; i < childCount; i++) {
            View child = getChildAt(i);
            if (child.getVisibility() != View.GONE) {
                return child;
            }
        }
        return null;
    }

    private int getMaxExpandHeight(View view) {
        if (view instanceof ExpandableNotificationRow) {
            ExpandableNotificationRow row = (ExpandableNotificationRow) view;
            return row.getMaximumAllowedExpandHeight();
        }
        return view.getHeight();
    }

    private int getContentHeight() {
        return mContentHeight;
    }
+204 −130

File changed.

Preview size limit exceeded, changes collapsed.

Loading