Merge "Expose locations from NotifStackScrollLayout"
This commit is contained in:
committed by
Android (Google) Code Review
commit
892c574ecc
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user