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

Commit 1685e634 authored by Selim Cinek's avatar Selim Cinek
Browse files

Further improved NotificationStackScroller

The top card is now collapsed during the pulldown of
the notification shade and expanded during the transition.
The scrollstate is also reset once the shade is closed.

Change-Id: Ibf17eef1f338d674c545e5bf55261e60db62b2ce
parent 9817ddd4
Loading
Loading
Loading
Loading
+13 −9
Original line number Diff line number Diff line
@@ -138,7 +138,8 @@ public abstract class BaseStatusBar extends SystemUI implements

    protected IDreamManager mDreamManager;
    PowerManager mPowerManager;
    protected int mRowHeight;
    protected int mRowMinHeight;
    protected int mRowMaxHeight;

    // public mode, private notifications, etc
    private boolean mLockscreenPublicMode = false;
@@ -880,7 +881,7 @@ public abstract class BaseStatusBar extends SystemUI implements
            }
        }
        entry.row = row;
        entry.row.setRowHeight(mRowHeight);
        entry.row.setHeightRange(mRowMinHeight, mRowMaxHeight);
        entry.content = content;
        entry.expanded = contentViewLocal;
        entry.expandedPublic = publicViewLocal;
@@ -1055,17 +1056,19 @@ public abstract class BaseStatusBar extends SystemUI implements
    }

    protected void updateExpansionStates() {

        // TODO: Handle user expansion better
        int N = mNotificationData.size();
        for (int i = 0; i < N; i++) {
            NotificationData.Entry entry = mNotificationData.get(i);
            if (!entry.row.isUserLocked()) {
                if (i == (N-1)) {
                    if (DEBUG) Log.d(TAG, "expanding top notification at " + i);
                    entry.row.setExpanded(true);
                    entry.row.setSystemExpanded(true);
                } else {
                    if (!entry.row.isUserExpanded()) {
                        if (DEBUG) Log.d(TAG, "collapsing notification at " + i);
                        entry.row.setExpanded(false);
                        entry.row.setSystemExpanded(false);
                    } else {
                        if (DEBUG) Log.d(TAG, "ignoring user-modified notification at " + i);
                    }
@@ -1218,13 +1221,14 @@ public abstract class BaseStatusBar extends SystemUI implements
            if (DEBUG) Log.d(TAG, "contents was " + (contentsUnchanged ? "unchanged" : "changed"));
            if (DEBUG) Log.d(TAG, "order was " + (orderUnchanged ? "unchanged" : "changed"));
            if (DEBUG) Log.d(TAG, "notification is " + (isTopAnyway ? "top" : "not top"));
            final boolean wasExpanded = oldEntry.row.isUserExpanded();
            removeNotificationViews(key);
            addNotificationViews(key, notification);  // will also replace the heads up
            if (wasExpanded) {
            final NotificationData.Entry newEntry = mNotificationData.findByKey(key);
                newEntry.row.setExpanded(true);
                newEntry.row.setUserExpanded(true);
            final boolean userChangedExpansion = oldEntry.row.hasUserChangedExpansion();
            if (userChangedExpansion) {
                boolean userExpanded = oldEntry.row.isUserExpanded();
                newEntry.row.applyExpansionToLayout(userExpanded);
                newEntry.row.setUserExpanded(userExpanded);
            }
        }

+124 −15
Original line number Diff line number Diff line
@@ -22,30 +22,49 @@ import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;

import com.android.internal.widget.SizeAdaptiveLayout;
import com.android.systemui.R;

public class ExpandableNotificationRow extends FrameLayout {
    private int mRowHeight;
    private int mRowMinHeight;
    private int mRowMaxHeight;

    /** does this row contain layouts that can adapt to row expansion */
    /** Does this row contain layouts that can adapt to row expansion */
    private boolean mExpandable;
    /** has the user manually expanded this row */
    /** Has the user actively changed the expansion state of this row */
    private boolean mHasUserChangedExpansion;
    /** If {@link #mHasUserChangedExpansion}, has the user expanded this row */
    private boolean mUserExpanded;
    /** is the user touching this row */
    /** Is the user touching this row */
    private boolean mUserLocked;
    /** are we showing the "public" version */
    /** Are we showing the "public" version */
    private boolean mShowingPublic;

    /**
     * Is this notification expanded by the system. The expansion state can be overridden by the
     * user expansion.
     */
    private boolean mIsSystemExpanded;
    private SizeAdaptiveLayout mPublicLayout;
    private SizeAdaptiveLayout mPrivateLayout;
    private int mMaxExpandHeight;
    private boolean mMaxHeightNeedsUpdate;

    public ExpandableNotificationRow(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public int getRowHeight() {
        return mRowHeight;
    @Override
    protected void onFinishInflate() {
        super.onFinishInflate();
        mPublicLayout = (SizeAdaptiveLayout) findViewById(R.id.expandedPublic);
        mPrivateLayout = (SizeAdaptiveLayout) findViewById(R.id.expanded);
    }

    public void setRowHeight(int rowHeight) {
        this.mRowHeight = rowHeight;
    public void setHeightRange(int rowMinHeight, int rowMaxHeight) {
        mRowMinHeight = rowMinHeight;
        mRowMaxHeight = rowMaxHeight;
        mMaxHeightNeedsUpdate = true;
    }

    public boolean isExpandable() {
@@ -56,11 +75,24 @@ public class ExpandableNotificationRow extends FrameLayout {
        mExpandable = expandable;
    }

    /**
     * @return whether the user has changed the expansion state
     */
    public boolean hasUserChangedExpansion() {
        return mHasUserChangedExpansion;
    }

    public boolean isUserExpanded() {
        return mUserExpanded;
    }

    /**
     * Set this notification to be expanded by the user
     *
     * @param userExpanded whether the user wants this notification to be expanded
     */
    public void setUserExpanded(boolean userExpanded) {
        mHasUserChangedExpansion = true;
        mUserExpanded = userExpanded;
    }

@@ -72,25 +104,102 @@ public class ExpandableNotificationRow extends FrameLayout {
        mUserLocked = userLocked;
    }

    public void setExpanded(boolean expand) {
    /**
     * @return has the system set this notification to be expanded
     */
    public boolean isSystemExpanded() {
        return mIsSystemExpanded;
    }

    /**
     * Set this notification to be expanded by the system.
     *
     * @param expand whether the system wants this notification to be expanded.
     */
    public void setSystemExpanded(boolean expand) {
        mIsSystemExpanded = expand;
        applyExpansionToLayout(expand);
    }

    /**
     * Apply an expansion state to the layout.
     *
     * @param expand should the layout be in the expanded state
     */
    public void applyExpansionToLayout(boolean expand) {
        ViewGroup.LayoutParams lp = getLayoutParams();
        if (expand && mExpandable) {
            lp.height = ViewGroup.LayoutParams.WRAP_CONTENT;
        } else {
            lp.height = mRowHeight;
            lp.height = mRowMinHeight;
        }
        setLayoutParams(lp);
    }

    /**
     * If {@link #isExpanded()} then this is the greatest possible height this view can
     * get and otherwise it is {@link #mRowMinHeight}.
     *
     * @return the maximum allowed expansion height of this view.
     */
    public int getMaximumAllowedExpandHeight() {
        boolean inExpansionState = isExpanded();
        if (!inExpansionState) {
            // not expanded, so we return the collapsed size
            return mRowMinHeight;
        }

        return mShowingPublic ? mRowMinHeight : getMaxExpandHeight();
    }



    private void updateMaxExpandHeight() {
        ViewGroup.LayoutParams lp = getLayoutParams();
        int oldHeight = lp.height;
        lp.height = ViewGroup.LayoutParams.WRAP_CONTENT;
        setLayoutParams(lp);
        measure(View.MeasureSpec.makeMeasureSpec(getMeasuredWidth(), View.MeasureSpec.EXACTLY),
                View.MeasureSpec.makeMeasureSpec(mRowMaxHeight, View.MeasureSpec.AT_MOST));
        lp.height = oldHeight;
        setLayoutParams(lp);
        mMaxExpandHeight = getMeasuredHeight();
    }

    /**
     * Check whether the view state is currently expanded. This is given by the system in {@link
     * #setSystemExpanded(boolean)} and can be overridden by user expansion or
     * collapsing in {@link #setUserExpanded(boolean)}. Note that the visual appearance of this
     * view can differ from this state, if layout params are modified from outside.
     *
     * @return whether the view state is currently expanded.
     */
    private boolean isExpanded() {
        return !hasUserChangedExpansion() && isSystemExpanded() || isUserExpanded();
    }

    @Override
    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
        super.onLayout(changed, left, top, right, bottom);
        mMaxHeightNeedsUpdate = true;
    }

    public void setShowingPublic(boolean show) {
        mShowingPublic = show;
        final ViewGroup publicLayout = (ViewGroup) findViewById(R.id.expandedPublic);

        // bail out if no public version
        if (publicLayout.getChildCount() == 0) return;
        if (mPublicLayout.getChildCount() == 0) return;

        // TODO: animation?
        publicLayout.setVisibility(show ? View.VISIBLE : View.GONE);
        findViewById(R.id.expanded).setVisibility(show ? View.GONE : View.VISIBLE);
        mPublicLayout.setVisibility(show ? View.VISIBLE : View.GONE);
        mPrivateLayout.setVisibility(show ? View.GONE : View.VISIBLE);
    }

    public int getMaxExpandHeight() {
        if (mMaxHeightNeedsUpdate) {
            updateMaxExpandHeight();
            mMaxHeightNeedsUpdate = false;
        }
        return mMaxExpandHeight;
    }
}
+13 −0
Original line number Diff line number Diff line
@@ -139,6 +139,7 @@ public class NotificationPanelView extends PanelView {
     * @param expandedHeight the new expanded height
     */
    private void updateNotificationStackHeight(float expandedHeight) {
        mNotificationStackScroller.setIsExpanded(expandedHeight > 0.0f);
        float childOffset = getRelativeTop(mNotificationStackScroller)
                - mNotificationParent.getTranslationY();
        int newStackHeight = (int) (expandedHeight - childOffset);
@@ -168,4 +169,16 @@ public class NotificationPanelView extends PanelView {
    protected int getDesiredMeasureHeight() {
        return mMaxPanelHeight;
    }

    @Override
    protected void onExpandingStarted() {
        super.onExpandingStarted();
        mNotificationStackScroller.onExpansionStarted();
    }

    @Override
    protected void onExpandingFinished() {
        super.onExpandingFinished();
        mNotificationStackScroller.onExpansionStopped();
    }
}
+23 −2
Original line number Diff line number Diff line
@@ -216,6 +216,7 @@ public class PanelView extends FrameLayout {
                mTimeAnimator.end();
                mRubberbanding = false;
                mClosing = false;
                onExpandingFinished();
            }
        }
    };
@@ -230,6 +231,12 @@ public class PanelView extends FrameLayout {
        mRubberbandingEnabled = enable;
    }

    protected void onExpandingFinished() {
    }

    protected void onExpandingStarted() {
    }

    private void runPeekAnimation() {
        if (DEBUG) logf("peek to height=%.1f", mPeekHeight);
        if (mTimeAnimator.isStarted()) {
@@ -398,7 +405,7 @@ public class PanelView extends FrameLayout {
                initVelocityTracker();
                trackMovement(event);
                mTimeAnimator.cancel(); // end any outstanding animations
                mBar.onTrackingStarted(PanelView.this);
                onTrackingStarted();
                mInitialOffsetOnTouch = mExpandedHeight;
                if (mExpandedHeight == 0) {
                    mJustPeeked = true;
@@ -443,7 +450,7 @@ public class PanelView extends FrameLayout {
                    mHandleView.setPressed(false);
                    postInvalidate(); // catch the press state change
                }
                mBar.onTrackingStopped(PanelView.this);
                onTrackingStopped();
                trackMovement(event);

                float vel = getCurrentVelocity();
@@ -458,6 +465,15 @@ public class PanelView extends FrameLayout {
        return true;
    }

    protected void onTrackingStopped() {
        mBar.onTrackingStopped(PanelView.this);
    }

    protected void onTrackingStarted() {
        mBar.onTrackingStarted(PanelView.this);
        onExpandingStarted();
    }

    private float getCurrentVelocity() {
        float vel = 0;
        float yVel = 0, xVel = 0;
@@ -561,6 +577,7 @@ public class PanelView extends FrameLayout {
                        mInitialOffsetOnTouch = mExpandedHeight;
                        mInitialTouchY = y;
                        mTracking = true;
                        onTrackingStarted();
                        return true;
                    }
                }
@@ -598,6 +615,8 @@ public class PanelView extends FrameLayout {

        if (always||mVel != 0) {
            animationTick(0); // begin the animation
        } else {
            onExpandingFinished();
        }
    }

@@ -770,6 +789,7 @@ public class PanelView extends FrameLayout {
        if (!isFullyCollapsed()) {
            mTimeAnimator.cancel();
            mClosing = true;
            onExpandingStarted();
            // collapse() should never be a rubberband, even if an animation is already running
            mRubberbanding = false;
            fling(-mSelfCollapseVelocityPx, /*always=*/ true);
@@ -780,6 +800,7 @@ public class PanelView extends FrameLayout {
        if (DEBUG) logf("expand: " + this);
        if (isFullyCollapsed()) {
            mBar.startOpeningPanel(this);
            onExpandingStarted();
            fling(mSelfExpandVelocityPx, /*always=*/ true);
        } else if (DEBUG) {
            if (DEBUG) logf("skipping expansion: is expanded");
+2 −1
Original line number Diff line number Diff line
@@ -2641,7 +2641,8 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode {
        }

        mHeadsUpNotificationDecay = res.getInteger(R.integer.heads_up_notification_decay);
        mRowHeight =  res.getDimensionPixelSize(R.dimen.notification_row_min_height);
        mRowMinHeight =  res.getDimensionPixelSize(R.dimen.notification_row_min_height);
        mRowMaxHeight =  res.getDimensionPixelSize(R.dimen.notification_row_max_height);

        if (false) Log.v(TAG, "updateResources");
    }
Loading