Merge "Expose locations from NotifStackScrollLayout"
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.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.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 @@
/**
* 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 @@
// currently the padding is in the elements themself
mPaddingBetweenElements = 0;
mStackScrollAlgorithm = new StackScrollAlgorithm(context);
- mCurrentStackScrollState = null;
}
@Override
@@ -188,6 +191,24 @@
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 @@
*/
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 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 @@
*/
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 @@
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 @@
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 @@
// 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 @@
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 @@
if (childHeight != (int) newSize) {
childViewState.height = (int) newSize;
}
+ childViewState.location = StackScrollState.ViewState.LOCATION_MAIN_AREA;
+
return nextYPosition;
}
@@ -206,6 +220,7 @@
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 @@
> 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 @@
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 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 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;
}
}