Loading packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java +33 −5 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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. Loading Loading @@ -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); Loading Loading @@ -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 Loading Loading @@ -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(); Loading @@ -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 } Loading Loading @@ -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); } } packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java +26 −8 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading Loading @@ -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; Loading @@ -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: Loading @@ -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 / Loading @@ -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; Loading @@ -192,6 +204,8 @@ public class StackScrollAlgorithm { if (childHeight != (int) newSize) { childViewState.height = (int) newSize; } childViewState.location = StackScrollState.ViewState.LOCATION_MAIN_AREA; return nextYPosition; } Loading @@ -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) { Loading @@ -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 Loading @@ -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) { // 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; } Loading packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollState.java +20 −2 Original line number Diff line number Diff line Loading @@ -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() { Loading Loading @@ -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; } } Loading
packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java +33 −5 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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. Loading Loading @@ -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); Loading Loading @@ -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 Loading Loading @@ -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(); Loading @@ -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 } Loading Loading @@ -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); } }
packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java +26 −8 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading Loading @@ -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; Loading @@ -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: Loading @@ -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 / Loading @@ -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; Loading @@ -192,6 +204,8 @@ public class StackScrollAlgorithm { if (childHeight != (int) newSize) { childViewState.height = (int) newSize; } childViewState.location = StackScrollState.ViewState.LOCATION_MAIN_AREA; return nextYPosition; } Loading @@ -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) { Loading @@ -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 Loading @@ -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) { // 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; } Loading
packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollState.java +20 −2 Original line number Diff line number Diff line Loading @@ -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() { Loading Loading @@ -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; } }