diff options
3 files changed, 79 insertions, 15 deletions
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 ff8ea405..f6eeb6d 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java @@ -22,6 +22,7 @@ import android.content.res.Configuration; import android.graphics.Canvas; import android.graphics.Outline; import android.graphics.Paint; + import android.util.AttributeSet; import android.util.Log; @@ -37,6 +38,7 @@ import com.android.systemui.ExpandHelper; import com.android.systemui.R; import com.android.systemui.SwipeHelper; import com.android.systemui.statusbar.ExpandableNotificationRow; +import com.android.systemui.statusbar.stack.StackScrollState.ViewState; /** * A layout which handles a dynamic amount of notifications and presents them in a scrollable stack. @@ -86,7 +88,9 @@ public class NotificationStackScrollLayout extends ViewGroup /** * The current State this Layout is in */ - private StackScrollState mCurrentStackScrollState; + private final StackScrollState mCurrentStackScrollState = new StackScrollState(this); + + private OnChildLocationsChangedListener mListener; public NotificationStackScrollLayout(Context context) { this(context, null); @@ -153,7 +157,6 @@ public class NotificationStackScrollLayout extends ViewGroup // currently the padding is in the elements themself mPaddingBetweenElements = 0; mStackScrollAlgorithm = new StackScrollAlgorithm(context); - mCurrentStackScrollState = null; } @Override @@ -188,6 +191,24 @@ public class NotificationStackScrollLayout extends ViewGroup updateContentHeight(); } + public void setChildLocationsChangedListener(OnChildLocationsChangedListener listener) { + mListener = listener; + } + + /** + * Returns the location the given child is currently rendered at. + * + * @param child the child to get the location for + * @return one of {@link ViewState}'s <code>LOCATION_*</code> constants + */ + public int getChildLocation(View child) { + ViewState childViewState = mCurrentStackScrollState.getViewStateForView(child); + if (childViewState == null) { + return ViewState.LOCATION_UNKNOWN; + } + return childViewState.location; + } + private void setMaxLayoutHeight(int maxLayoutHeight) { mMaxLayoutHeight = maxLayoutHeight; updateAlgorithmHeight(); @@ -203,13 +224,13 @@ public class NotificationStackScrollLayout extends ViewGroup */ private void updateChildren() { if (!isCurrentlyAnimating()) { - if (mCurrentStackScrollState == null) { - mCurrentStackScrollState = new StackScrollState(this); - } mCurrentStackScrollState.setScrollY(mOwnScrollY); mStackScrollAlgorithm.getStackScrollState(mCurrentStackScrollState); mCurrentStackScrollState.apply(); mOwnScrollY = mCurrentStackScrollState.getScrollY(); + if (mListener != null) { + mListener.onChildLocationsChanged(this); + } } else { // TODO: handle animation } @@ -823,4 +844,11 @@ public class NotificationStackScrollLayout extends ViewGroup public View getHostView() { return this; } + + /** + * A listener that is notified when some child locations might have changed. + */ + public interface OnChildLocationsChangedListener { + public void onChildLocationsChanged(NotificationStackScrollLayout stackScrollLayout); + } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java index 9db4e77..6d2ba6a 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java @@ -17,6 +17,7 @@ package com.android.systemui.statusbar.stack; import android.content.Context; +import android.util.Log; import android.view.View; import android.view.ViewGroup; import com.android.systemui.R; @@ -28,6 +29,8 @@ import com.android.systemui.R; */ public class StackScrollAlgorithm { + private static final String LOG_TAG = "StackScrollAlgorithm"; + private static final int MAX_ITEMS_IN_BOTTOM_STACK = 3; private static final int MAX_ITEMS_IN_TOP_STACK = 3; @@ -130,6 +133,7 @@ public class StackScrollAlgorithm { View child = hostView.getChildAt(i); StackScrollState.ViewState childViewState = resultState.getViewStateForView(child); childViewState.yTranslation = currentYPosition; + childViewState.location = StackScrollState.ViewState.LOCATION_UNKNOWN; int childHeight = child.getHeight(); // The y position after this element float nextYPosition = currentYPosition + childHeight + mPaddingBetweenElements; @@ -143,12 +147,12 @@ public class StackScrollAlgorithm { nextYPosition = updateStateForTopStackChild(algorithmState, numberOfElementsCompletelyIn, i, childViewState); - } else if (i == algorithmState.lastTopStackIndex) { // Case 2: // First element of regular scrollview comes next, so the position is just the // scrolling position nextYPosition = scrollOffset; + childViewState.location = StackScrollState.ViewState.LOCATION_TOP_STACK_PEEKING; } else if (nextYPosition >= transitioningPositionStart) { if (currentYPosition >= transitioningPositionStart) { // Case 3: @@ -156,8 +160,6 @@ public class StackScrollAlgorithm { // bottom of the screen so we are fully in the bottom stack nextYPosition = updateStateForChildFullyInBottomStack(algorithmState, transitioningPositionStart, childViewState, childHeight); - - } else { // Case 4: // According to the regular scroll view we are currently translating out of / @@ -167,6 +169,16 @@ public class StackScrollAlgorithm { currentYPosition, childViewState, childHeight, nextYPosition); } + } else { + childViewState.location = StackScrollState.ViewState.LOCATION_MAIN_AREA; + } + // The first card is always rendered. + if (i == 0) { + childViewState.alpha = 1.0f; + childViewState.location = StackScrollState.ViewState.LOCATION_FIRST_CARD; + } + if (childViewState.location == StackScrollState.ViewState.LOCATION_UNKNOWN) { + Log.wtf(LOG_TAG, "Failed to assign location for child " + i); } currentYPosition = nextYPosition; yPositionInScrollView = yPositionInScrollViewAfterElement; @@ -192,6 +204,8 @@ public class StackScrollAlgorithm { if (childHeight != (int) newSize) { childViewState.height = (int) newSize; } + childViewState.location = StackScrollState.ViewState.LOCATION_MAIN_AREA; + return nextYPosition; } @@ -206,6 +220,7 @@ public class StackScrollAlgorithm { nextYPosition = transitioningPositionStart + mBottomStackIndentationFunctor.getValue( algorithmState.itemsInBottomStack); + childViewState.location = StackScrollState.ViewState.LOCATION_BOTTOM_STACK_PEEKING; } else { // we are fully inside the stack if (algorithmState.itemsInBottomStack > MAX_ITEMS_IN_BOTTOM_STACK + 2) { @@ -214,6 +229,7 @@ public class StackScrollAlgorithm { > MAX_ITEMS_IN_BOTTOM_STACK + 1) { childViewState.alpha = 1.0f - algorithmState.partialInBottom; } + childViewState.location = StackScrollState.ViewState.LOCATION_BOTTOM_STACK_HIDDEN; nextYPosition = transitioningPositionStart + mBottomStackPeekSize; } // TODO: only temporarily collapse @@ -237,14 +253,16 @@ public class StackScrollAlgorithm { nextYPosition = mCollapsedSize + mPaddingBetweenElements - mTopStackIndentationFunctor.getValue( algorithmState.itemsInTopStack - i - 1); - if (paddedIndex == 0 && i != 0) { + if (paddedIndex == 0) { childViewState.alpha = 1.0f - algorithmState.partialInTop; + childViewState.location = StackScrollState.ViewState.LOCATION_TOP_STACK_HIDDEN; + } else { + childViewState.location = StackScrollState.ViewState.LOCATION_TOP_STACK_PEEKING; } } else { - // We are hidden behind the top card and faded out, so we can hide ourselfs - if (i != 0) { - childViewState.alpha = 0.0f; - } + // We are hidden behind the top card and faded out, so we can hide ourselves. + childViewState.alpha = 0.0f; + childViewState.location = StackScrollState.ViewState.LOCATION_TOP_STACK_HIDDEN; } return nextYPosition; } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollState.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollState.java index f72a52f..881730a 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollState.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollState.java @@ -45,7 +45,7 @@ public class StackScrollState { public StackScrollState(ViewGroup hostView) { mHostView = hostView; - mStateMap = new HashMap<View, ViewState>(mHostView.getChildCount()); + mStateMap = new HashMap<View, ViewState>(); } public ViewGroup getHostView() { @@ -144,10 +144,28 @@ public class StackScrollState { } - public class ViewState { + public static class ViewState { + + // These are flags such that we can create masks for filtering. + + public static final int LOCATION_UNKNOWN = 0x00; + public static final int LOCATION_FIRST_CARD = 0x01; + public static final int LOCATION_TOP_STACK_HIDDEN = 0x02; + public static final int LOCATION_TOP_STACK_PEEKING = 0x04; + public static final int LOCATION_MAIN_AREA = 0x08; + public static final int LOCATION_BOTTOM_STACK_PEEKING = 0x10; + public static final int LOCATION_BOTTOM_STACK_HIDDEN = 0x20; + float alpha; float yTranslation; float zTranslation; int height; + + /** + * The location this view is currently rendered at. + * + * <p>See <code>LOCATION_</code> flags.</p> + */ + int location; } } |
