Merge "Made stack scroller animation and apply logic reusable"
This commit is contained in:
@@ -161,7 +161,7 @@ import com.android.systemui.statusbar.policy.UserSwitcherController;
|
||||
import com.android.systemui.statusbar.policy.ZenModeController;
|
||||
import com.android.systemui.statusbar.stack.NotificationStackScrollLayout;
|
||||
import com.android.systemui.statusbar.stack.NotificationStackScrollLayout.OnChildLocationsChangedListener;
|
||||
import com.android.systemui.statusbar.stack.StackScrollState.ViewState;
|
||||
import com.android.systemui.statusbar.stack.StackViewState;
|
||||
import com.android.systemui.volume.VolumeComponent;
|
||||
|
||||
import java.io.FileDescriptor;
|
||||
@@ -444,10 +444,10 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
|
||||
// Fingerprint (as computed by getLoggingFingerprint() of the last logged state.
|
||||
private int mLastLoggedStateFingerprint;
|
||||
|
||||
private static final int VISIBLE_LOCATIONS = ViewState.LOCATION_FIRST_CARD
|
||||
| ViewState.LOCATION_TOP_STACK_PEEKING
|
||||
| ViewState.LOCATION_MAIN_AREA
|
||||
| ViewState.LOCATION_BOTTOM_STACK_PEEKING;
|
||||
private static final int VISIBLE_LOCATIONS = StackViewState.LOCATION_FIRST_CARD
|
||||
| StackViewState.LOCATION_TOP_STACK_PEEKING
|
||||
| StackViewState.LOCATION_MAIN_AREA
|
||||
| StackViewState.LOCATION_BOTTOM_STACK_PEEKING;
|
||||
|
||||
private final OnChildLocationsChangedListener mNotificationLocationsChangedListener =
|
||||
new OnChildLocationsChangedListener() {
|
||||
|
||||
@@ -46,7 +46,6 @@ import com.android.systemui.statusbar.StackScrollerDecorView;
|
||||
import com.android.systemui.statusbar.StatusBarState;
|
||||
import com.android.systemui.statusbar.phone.PhoneStatusBar;
|
||||
import com.android.systemui.statusbar.policy.ScrollAdapter;
|
||||
import com.android.systemui.statusbar.stack.StackScrollState.ViewState;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
@@ -375,15 +374,15 @@ public class NotificationStackScrollLayout extends ViewGroup
|
||||
* 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
|
||||
* @return one of {@link StackViewState}'s <code>LOCATION_*</code> constants
|
||||
*/
|
||||
public int getChildLocation(View child) {
|
||||
ViewState childViewState = mCurrentStackScrollState.getViewStateForView(child);
|
||||
StackViewState childViewState = mCurrentStackScrollState.getViewStateForView(child);
|
||||
if (childViewState == null) {
|
||||
return ViewState.LOCATION_UNKNOWN;
|
||||
return StackViewState.LOCATION_UNKNOWN;
|
||||
}
|
||||
if (childViewState.gone) {
|
||||
return ViewState.LOCATION_GONE;
|
||||
return StackViewState.LOCATION_GONE;
|
||||
}
|
||||
return childViewState.location;
|
||||
}
|
||||
|
||||
@@ -178,7 +178,7 @@ public class StackScrollAlgorithm {
|
||||
int childCount = algorithmState.visibleChildren.size();
|
||||
for (int i = 0; i < childCount; i++) {
|
||||
View child = algorithmState.visibleChildren.get(i);
|
||||
StackScrollState.ViewState childViewState = resultState.getViewStateForView(child);
|
||||
StackViewState childViewState = resultState.getViewStateForView(child);
|
||||
|
||||
// The speed bump can also be gone, so equality needs to be taken when comparing
|
||||
// indices.
|
||||
@@ -194,7 +194,7 @@ public class StackScrollAlgorithm {
|
||||
int childCount = algorithmState.visibleChildren.size();
|
||||
for (int i = 0; i < childCount; i++) {
|
||||
ExpandableView child = algorithmState.visibleChildren.get(i);
|
||||
StackScrollState.ViewState state = resultState.getViewStateForView(child);
|
||||
StackViewState state = resultState.getViewStateForView(child);
|
||||
float newYTranslation = state.yTranslation + state.height * (1f - state.scale) / 2f;
|
||||
float newHeight = state.height * state.scale;
|
||||
// apply clipping and shadow
|
||||
@@ -242,8 +242,8 @@ public class StackScrollAlgorithm {
|
||||
* @param backgroundHeight the desired background height. The shadows of the view will be
|
||||
* based on this height and the content will be clipped from the top
|
||||
*/
|
||||
private void updateChildClippingAndBackground(StackScrollState.ViewState state,
|
||||
float realHeight, float clipHeight, float backgroundHeight) {
|
||||
private void updateChildClippingAndBackground(StackViewState state, float realHeight,
|
||||
float clipHeight, float backgroundHeight) {
|
||||
if (realHeight > clipHeight) {
|
||||
// Rather overlap than create a hole.
|
||||
state.topOverLap = (int) Math.floor((realHeight - clipHeight) / state.scale);
|
||||
@@ -270,7 +270,7 @@ public class StackScrollAlgorithm {
|
||||
int childCount = algorithmState.visibleChildren.size();
|
||||
for (int i = 0; i < childCount; i++) {
|
||||
View child = algorithmState.visibleChildren.get(i);
|
||||
StackScrollState.ViewState childViewState = resultState.getViewStateForView(child);
|
||||
StackViewState childViewState = resultState.getViewStateForView(child);
|
||||
childViewState.dimmed = dimmed;
|
||||
childViewState.dark = dark;
|
||||
childViewState.hideSensitive = hideSensitive;
|
||||
@@ -297,14 +297,14 @@ public class StackScrollAlgorithm {
|
||||
if (!draggedViews.contains(nextChild)) {
|
||||
// only if the view is not dragged itself we modify its state to be fully
|
||||
// visible
|
||||
StackScrollState.ViewState viewState = resultState.getViewStateForView(
|
||||
StackViewState viewState = resultState.getViewStateForView(
|
||||
nextChild);
|
||||
// The child below the dragged one must be fully visible
|
||||
viewState.alpha = 1;
|
||||
}
|
||||
|
||||
// Lets set the alpha to the one it currently has, as its currently being dragged
|
||||
StackScrollState.ViewState viewState = resultState.getViewStateForView(draggedView);
|
||||
StackViewState viewState = resultState.getViewStateForView(draggedView);
|
||||
// The dragged child should keep the set alpha
|
||||
viewState.alpha = draggedView.getAlpha();
|
||||
}
|
||||
@@ -320,12 +320,14 @@ public class StackScrollAlgorithm {
|
||||
int childCount = hostView.getChildCount();
|
||||
state.visibleChildren.clear();
|
||||
state.visibleChildren.ensureCapacity(childCount);
|
||||
int notGoneIndex = 0;
|
||||
for (int i = 0; i < childCount; i++) {
|
||||
ExpandableView v = (ExpandableView) hostView.getChildAt(i);
|
||||
if (v.getVisibility() != View.GONE) {
|
||||
StackScrollState.ViewState viewState = resultState.getViewStateForView(v);
|
||||
viewState.notGoneIndex = state.visibleChildren.size();
|
||||
StackViewState viewState = resultState.getViewStateForView(v);
|
||||
viewState.notGoneIndex = notGoneIndex;
|
||||
state.visibleChildren.add(v);
|
||||
notGoneIndex++;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -355,8 +357,8 @@ public class StackScrollAlgorithm {
|
||||
int numberOfElementsCompletelyIn = (int) algorithmState.itemsInTopStack;
|
||||
for (int i = 0; i < childCount; i++) {
|
||||
ExpandableView child = algorithmState.visibleChildren.get(i);
|
||||
StackScrollState.ViewState childViewState = resultState.getViewStateForView(child);
|
||||
childViewState.location = StackScrollState.ViewState.LOCATION_UNKNOWN;
|
||||
StackViewState childViewState = resultState.getViewStateForView(child);
|
||||
childViewState.location = StackViewState.LOCATION_UNKNOWN;
|
||||
int childHeight = getMaxAllowedChildHeight(child);
|
||||
float yPositionInScrollViewAfterElement = yPositionInScrollView
|
||||
+ childHeight
|
||||
@@ -413,7 +415,7 @@ public class StackScrollAlgorithm {
|
||||
} else {
|
||||
// Case 3:
|
||||
// We are in the regular scroll area.
|
||||
childViewState.location = StackScrollState.ViewState.LOCATION_MAIN_AREA;
|
||||
childViewState.location = StackViewState.LOCATION_MAIN_AREA;
|
||||
clampYTranslation(childViewState, childHeight);
|
||||
}
|
||||
|
||||
@@ -427,9 +429,9 @@ public class StackScrollAlgorithm {
|
||||
bottomPeekStart - mCollapseSecondCardPadding
|
||||
- childViewState.yTranslation, mCollapsedSize);
|
||||
}
|
||||
childViewState.location = StackScrollState.ViewState.LOCATION_FIRST_CARD;
|
||||
childViewState.location = StackViewState.LOCATION_FIRST_CARD;
|
||||
}
|
||||
if (childViewState.location == StackScrollState.ViewState.LOCATION_UNKNOWN) {
|
||||
if (childViewState.location == StackViewState.LOCATION_UNKNOWN) {
|
||||
Log.wtf(LOG_TAG, "Failed to assign location for child " + i);
|
||||
}
|
||||
currentYPosition = childViewState.yTranslation + childHeight + mPaddingBetweenElements;
|
||||
@@ -445,7 +447,7 @@ public class StackScrollAlgorithm {
|
||||
* @param childViewState the view state of the child
|
||||
* @param childHeight the height of this child
|
||||
*/
|
||||
private void clampYTranslation(StackScrollState.ViewState childViewState, int childHeight) {
|
||||
private void clampYTranslation(StackViewState childViewState, int childHeight) {
|
||||
clampPositionToBottomStackStart(childViewState, childHeight);
|
||||
clampPositionToTopStackEnd(childViewState, childHeight);
|
||||
}
|
||||
@@ -457,7 +459,7 @@ public class StackScrollAlgorithm {
|
||||
* @param childViewState the view state of the child
|
||||
* @param childHeight the height of this child
|
||||
*/
|
||||
private void clampPositionToBottomStackStart(StackScrollState.ViewState childViewState,
|
||||
private void clampPositionToBottomStackStart(StackViewState childViewState,
|
||||
int childHeight) {
|
||||
childViewState.yTranslation = Math.min(childViewState.yTranslation,
|
||||
mInnerHeight - mBottomStackPeekSize - mCollapseSecondCardPadding - childHeight);
|
||||
@@ -470,7 +472,7 @@ public class StackScrollAlgorithm {
|
||||
* @param childViewState the view state of the child
|
||||
* @param childHeight the height of this child
|
||||
*/
|
||||
private void clampPositionToTopStackEnd(StackScrollState.ViewState childViewState,
|
||||
private void clampPositionToTopStackEnd(StackViewState childViewState,
|
||||
int childHeight) {
|
||||
childViewState.yTranslation = Math.max(childViewState.yTranslation,
|
||||
mCollapsedSize - childHeight);
|
||||
@@ -489,7 +491,7 @@ public class StackScrollAlgorithm {
|
||||
|
||||
private void updateStateForChildTransitioningInBottom(StackScrollAlgorithmState algorithmState,
|
||||
float transitioningPositionStart, float bottomPeakStart, float currentYPosition,
|
||||
StackScrollState.ViewState childViewState, int childHeight) {
|
||||
StackViewState childViewState, int childHeight) {
|
||||
|
||||
// This is the transitioning element on top of bottom stack, calculate how far we are in.
|
||||
algorithmState.partialInBottom = 1.0f - (
|
||||
@@ -510,11 +512,11 @@ public class StackScrollAlgorithm {
|
||||
|
||||
// We want at least to be at the end of the top stack when collapsing
|
||||
clampPositionToTopStackEnd(childViewState, newHeight);
|
||||
childViewState.location = StackScrollState.ViewState.LOCATION_MAIN_AREA;
|
||||
childViewState.location = StackViewState.LOCATION_MAIN_AREA;
|
||||
}
|
||||
|
||||
private void updateStateForChildFullyInBottomStack(StackScrollAlgorithmState algorithmState,
|
||||
float transitioningPositionStart, StackScrollState.ViewState childViewState,
|
||||
float transitioningPositionStart, StackViewState childViewState,
|
||||
int childHeight) {
|
||||
|
||||
float currentYPosition;
|
||||
@@ -524,7 +526,7 @@ public class StackScrollAlgorithm {
|
||||
currentYPosition = transitioningPositionStart
|
||||
+ mBottomStackIndentationFunctor.getValue(algorithmState.itemsInBottomStack)
|
||||
- mPaddingBetweenElements;
|
||||
childViewState.location = StackScrollState.ViewState.LOCATION_BOTTOM_STACK_PEEKING;
|
||||
childViewState.location = StackViewState.LOCATION_BOTTOM_STACK_PEEKING;
|
||||
} else {
|
||||
// we are fully inside the stack
|
||||
if (algorithmState.itemsInBottomStack > MAX_ITEMS_IN_BOTTOM_STACK + 2) {
|
||||
@@ -533,7 +535,7 @@ public class StackScrollAlgorithm {
|
||||
> MAX_ITEMS_IN_BOTTOM_STACK + 1) {
|
||||
childViewState.alpha = 1.0f - algorithmState.partialInBottom;
|
||||
}
|
||||
childViewState.location = StackScrollState.ViewState.LOCATION_BOTTOM_STACK_HIDDEN;
|
||||
childViewState.location = StackViewState.LOCATION_BOTTOM_STACK_HIDDEN;
|
||||
currentYPosition = mInnerHeight;
|
||||
}
|
||||
childViewState.yTranslation = currentYPosition - childHeight;
|
||||
@@ -542,7 +544,7 @@ public class StackScrollAlgorithm {
|
||||
|
||||
private void updateStateForTopStackChild(StackScrollAlgorithmState algorithmState,
|
||||
int numberOfElementsCompletelyIn, int i, int childHeight,
|
||||
StackScrollState.ViewState childViewState, float scrollOffset) {
|
||||
StackViewState childViewState, float scrollOffset) {
|
||||
|
||||
|
||||
// First we calculate the index relative to the current stack window of size at most
|
||||
@@ -574,7 +576,7 @@ public class StackScrollAlgorithm {
|
||||
- mTopStackIndentationFunctor.getValue(numItemsBefore);
|
||||
childViewState.yTranslation = currentChildEndY - childHeight;
|
||||
}
|
||||
childViewState.location = StackScrollState.ViewState.LOCATION_TOP_STACK_PEEKING;
|
||||
childViewState.location = StackViewState.LOCATION_TOP_STACK_PEEKING;
|
||||
} else {
|
||||
if (paddedIndex == -1) {
|
||||
childViewState.alpha = 1.0f - algorithmState.partialInTop;
|
||||
@@ -583,7 +585,7 @@ public class StackScrollAlgorithm {
|
||||
childViewState.alpha = 0.0f;
|
||||
}
|
||||
childViewState.yTranslation = mCollapsedSize - childHeight;
|
||||
childViewState.location = StackScrollState.ViewState.LOCATION_TOP_STACK_HIDDEN;
|
||||
childViewState.location = StackViewState.LOCATION_TOP_STACK_HIDDEN;
|
||||
}
|
||||
|
||||
|
||||
@@ -605,7 +607,7 @@ public class StackScrollAlgorithm {
|
||||
// find the number of elements in the top stack.
|
||||
for (int i = 0; i < childCount; i++) {
|
||||
ExpandableView child = algorithmState.visibleChildren.get(i);
|
||||
StackScrollState.ViewState childViewState = resultState.getViewStateForView(child);
|
||||
StackViewState childViewState = resultState.getViewStateForView(child);
|
||||
int childHeight = getMaxAllowedChildHeight(child);
|
||||
float yPositionInScrollViewAfterElement = yPositionInScrollView
|
||||
+ childHeight
|
||||
@@ -676,7 +678,7 @@ public class StackScrollAlgorithm {
|
||||
int childCount = algorithmState.visibleChildren.size();
|
||||
for (int i = 0; i < childCount; i++) {
|
||||
View child = algorithmState.visibleChildren.get(i);
|
||||
StackScrollState.ViewState childViewState = resultState.getViewStateForView(child);
|
||||
StackViewState childViewState = resultState.getViewStateForView(child);
|
||||
if (i < algorithmState.itemsInTopStack) {
|
||||
float stackIndex = algorithmState.itemsInTopStack - i;
|
||||
|
||||
|
||||
@@ -39,13 +39,13 @@ public class StackScrollState {
|
||||
private static final String CHILD_NOT_FOUND_TAG = "StackScrollStateNoSuchChild";
|
||||
|
||||
private final ViewGroup mHostView;
|
||||
private Map<ExpandableView, ViewState> mStateMap;
|
||||
private Map<ExpandableView, StackViewState> mStateMap;
|
||||
private final Rect mClipRect = new Rect();
|
||||
private final int mClearAllTopPadding;
|
||||
|
||||
public StackScrollState(ViewGroup hostView) {
|
||||
mHostView = hostView;
|
||||
mStateMap = new HashMap<ExpandableView, ViewState>();
|
||||
mStateMap = new HashMap<ExpandableView, StackViewState>();
|
||||
mClearAllTopPadding = hostView.getContext().getResources().getDimensionPixelSize(
|
||||
R.dimen.clear_all_padding_top);
|
||||
}
|
||||
@@ -58,20 +58,24 @@ public class StackScrollState {
|
||||
int numChildren = mHostView.getChildCount();
|
||||
for (int i = 0; i < numChildren; i++) {
|
||||
ExpandableView child = (ExpandableView) mHostView.getChildAt(i);
|
||||
ViewState viewState = mStateMap.get(child);
|
||||
if (viewState == null) {
|
||||
viewState = new ViewState();
|
||||
mStateMap.put(child, viewState);
|
||||
}
|
||||
// initialize with the default values of the view
|
||||
viewState.height = child.getIntrinsicHeight();
|
||||
viewState.gone = child.getVisibility() == View.GONE;
|
||||
viewState.alpha = 1;
|
||||
viewState.notGoneIndex = -1;
|
||||
resetViewState(child);
|
||||
}
|
||||
}
|
||||
|
||||
public ViewState getViewStateForView(View requestedView) {
|
||||
private void resetViewState(ExpandableView view) {
|
||||
StackViewState viewState = mStateMap.get(view);
|
||||
if (viewState == null) {
|
||||
viewState = new StackViewState();
|
||||
mStateMap.put(view, viewState);
|
||||
}
|
||||
// initialize with the default values of the view
|
||||
viewState.height = view.getIntrinsicHeight();
|
||||
viewState.gone = view.getVisibility() == View.GONE;
|
||||
viewState.alpha = 1;
|
||||
viewState.notGoneIndex = -1;
|
||||
}
|
||||
|
||||
public StackViewState getViewStateForView(View requestedView) {
|
||||
return mStateMap.get(requestedView);
|
||||
}
|
||||
|
||||
@@ -87,105 +91,126 @@ public class StackScrollState {
|
||||
int numChildren = mHostView.getChildCount();
|
||||
for (int i = 0; i < numChildren; i++) {
|
||||
ExpandableView child = (ExpandableView) mHostView.getChildAt(i);
|
||||
ViewState state = mStateMap.get(child);
|
||||
if (state == null) {
|
||||
Log.wtf(CHILD_NOT_FOUND_TAG, "No child state was found when applying this state " +
|
||||
"to the hostView");
|
||||
StackViewState state = mStateMap.get(child);
|
||||
if (!applyState(child, state)) {
|
||||
continue;
|
||||
}
|
||||
if (!state.gone) {
|
||||
float alpha = child.getAlpha();
|
||||
float yTranslation = child.getTranslationY();
|
||||
float xTranslation = child.getTranslationX();
|
||||
float zTranslation = child.getTranslationZ();
|
||||
float scale = child.getScaleX();
|
||||
int height = child.getActualHeight();
|
||||
float newAlpha = state.alpha;
|
||||
float newYTranslation = state.yTranslation;
|
||||
float newZTranslation = state.zTranslation;
|
||||
float newScale = state.scale;
|
||||
int newHeight = state.height;
|
||||
boolean becomesInvisible = newAlpha == 0.0f;
|
||||
if (alpha != newAlpha && xTranslation == 0) {
|
||||
// apply layer type
|
||||
boolean becomesFullyVisible = newAlpha == 1.0f;
|
||||
boolean newLayerTypeIsHardware = !becomesInvisible && !becomesFullyVisible;
|
||||
int layerType = child.getLayerType();
|
||||
int newLayerType = newLayerTypeIsHardware
|
||||
? View.LAYER_TYPE_HARDWARE
|
||||
: View.LAYER_TYPE_NONE;
|
||||
if (layerType != newLayerType) {
|
||||
child.setLayerType(newLayerType, null);
|
||||
}
|
||||
|
||||
// apply alpha
|
||||
child.setAlpha(newAlpha);
|
||||
}
|
||||
|
||||
// apply visibility
|
||||
int oldVisibility = child.getVisibility();
|
||||
int newVisibility = becomesInvisible ? View.INVISIBLE : View.VISIBLE;
|
||||
if (newVisibility != oldVisibility) {
|
||||
child.setVisibility(newVisibility);
|
||||
}
|
||||
|
||||
// apply yTranslation
|
||||
if (yTranslation != newYTranslation) {
|
||||
child.setTranslationY(newYTranslation);
|
||||
}
|
||||
|
||||
// apply zTranslation
|
||||
if (zTranslation != newZTranslation) {
|
||||
child.setTranslationZ(newZTranslation);
|
||||
}
|
||||
|
||||
// apply scale
|
||||
if (scale != newScale) {
|
||||
child.setScaleX(newScale);
|
||||
child.setScaleY(newScale);
|
||||
}
|
||||
|
||||
// apply height
|
||||
if (height != newHeight) {
|
||||
child.setActualHeight(newHeight, false /* notifyListeners */);
|
||||
}
|
||||
|
||||
// apply dimming
|
||||
child.setDimmed(state.dimmed, false /* animate */);
|
||||
|
||||
// apply dark
|
||||
child.setDark(state.dark, false /* animate */, 0 /* delay */);
|
||||
|
||||
// apply hiding sensitive
|
||||
child.setHideSensitive(
|
||||
state.hideSensitive, false /* animated */, 0 /* delay */, 0 /* duration */);
|
||||
|
||||
// apply speed bump state
|
||||
child.setBelowSpeedBump(state.belowSpeedBump);
|
||||
|
||||
// apply clipping
|
||||
float oldClipTopAmount = child.getClipTopAmount();
|
||||
if (oldClipTopAmount != state.clipTopAmount) {
|
||||
child.setClipTopAmount(state.clipTopAmount);
|
||||
}
|
||||
updateChildClip(child, newHeight, state.topOverLap);
|
||||
|
||||
if(child instanceof SpeedBumpView) {
|
||||
performSpeedBumpAnimation(i, (SpeedBumpView) child, state, 0);
|
||||
} else if (child instanceof DismissView) {
|
||||
DismissView dismissView = (DismissView) child;
|
||||
boolean visible = state.topOverLap < mClearAllTopPadding;
|
||||
dismissView.performVisibilityAnimation(visible && !dismissView.willBeGone());
|
||||
} else if (child instanceof EmptyShadeView) {
|
||||
EmptyShadeView emptyShadeView = (EmptyShadeView) child;
|
||||
boolean visible = state.topOverLap <= 0;
|
||||
emptyShadeView.performVisibilityAnimation(
|
||||
visible && !emptyShadeView.willBeGone());
|
||||
}
|
||||
if(child instanceof SpeedBumpView) {
|
||||
performSpeedBumpAnimation(i, (SpeedBumpView) child, state, 0);
|
||||
} else if (child instanceof DismissView) {
|
||||
DismissView dismissView = (DismissView) child;
|
||||
boolean visible = state.topOverLap < mClearAllTopPadding;
|
||||
dismissView.performVisibilityAnimation(visible && !dismissView.willBeGone());
|
||||
} else if (child instanceof EmptyShadeView) {
|
||||
EmptyShadeView emptyShadeView = (EmptyShadeView) child;
|
||||
boolean visible = state.topOverLap <= 0;
|
||||
emptyShadeView.performVisibilityAnimation(
|
||||
visible && !emptyShadeView.willBeGone());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies a {@link StackViewState} to an {@link ExpandableView}.
|
||||
*
|
||||
* @return whether the state was applied correctly
|
||||
*/
|
||||
public boolean applyState(ExpandableView view, StackViewState state) {
|
||||
if (state == null) {
|
||||
Log.wtf(CHILD_NOT_FOUND_TAG, "No child state was found when applying this state " +
|
||||
"to the hostView");
|
||||
return false;
|
||||
}
|
||||
if (state.gone) {
|
||||
return false;
|
||||
}
|
||||
applyViewState(view, state);
|
||||
|
||||
int height = view.getActualHeight();
|
||||
int newHeight = state.height;
|
||||
|
||||
// apply height
|
||||
if (height != newHeight) {
|
||||
view.setActualHeight(newHeight, false /* notifyListeners */);
|
||||
}
|
||||
|
||||
// apply dimming
|
||||
view.setDimmed(state.dimmed, false /* animate */);
|
||||
|
||||
// apply dark
|
||||
view.setDark(state.dark, false /* animate */, 0 /* delay */);
|
||||
|
||||
// apply hiding sensitive
|
||||
view.setHideSensitive(
|
||||
state.hideSensitive, false /* animated */, 0 /* delay */, 0 /* duration */);
|
||||
|
||||
// apply speed bump state
|
||||
view.setBelowSpeedBump(state.belowSpeedBump);
|
||||
|
||||
// apply clipping
|
||||
float oldClipTopAmount = view.getClipTopAmount();
|
||||
if (oldClipTopAmount != state.clipTopAmount) {
|
||||
view.setClipTopAmount(state.clipTopAmount);
|
||||
}
|
||||
updateChildClip(view, newHeight, state.topOverLap);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies a {@link ViewState} to a normal view.
|
||||
*/
|
||||
public void applyViewState(View view, ViewState state) {
|
||||
float alpha = view.getAlpha();
|
||||
float yTranslation = view.getTranslationY();
|
||||
float xTranslation = view.getTranslationX();
|
||||
float zTranslation = view.getTranslationZ();
|
||||
float scale = view.getScaleX();
|
||||
float newAlpha = state.alpha;
|
||||
float newYTranslation = state.yTranslation;
|
||||
float newZTranslation = state.zTranslation;
|
||||
float newScale = state.scale;
|
||||
boolean becomesInvisible = newAlpha == 0.0f;
|
||||
if (alpha != newAlpha && xTranslation == 0) {
|
||||
// apply layer type
|
||||
boolean becomesFullyVisible = newAlpha == 1.0f;
|
||||
boolean newLayerTypeIsHardware = !becomesInvisible && !becomesFullyVisible
|
||||
&& view.hasOverlappingRendering();
|
||||
int layerType = view.getLayerType();
|
||||
int newLayerType = newLayerTypeIsHardware
|
||||
? View.LAYER_TYPE_HARDWARE
|
||||
: View.LAYER_TYPE_NONE;
|
||||
if (layerType != newLayerType) {
|
||||
view.setLayerType(newLayerType, null);
|
||||
}
|
||||
|
||||
// apply alpha
|
||||
view.setAlpha(newAlpha);
|
||||
}
|
||||
|
||||
// apply visibility
|
||||
int oldVisibility = view.getVisibility();
|
||||
int newVisibility = becomesInvisible ? View.INVISIBLE : View.VISIBLE;
|
||||
if (newVisibility != oldVisibility) {
|
||||
view.setVisibility(newVisibility);
|
||||
}
|
||||
|
||||
// apply yTranslation
|
||||
if (yTranslation != newYTranslation) {
|
||||
view.setTranslationY(newYTranslation);
|
||||
}
|
||||
|
||||
// apply zTranslation
|
||||
if (zTranslation != newZTranslation) {
|
||||
view.setTranslationZ(newZTranslation);
|
||||
}
|
||||
|
||||
// apply scale
|
||||
if (scale != newScale) {
|
||||
view.setScaleX(newScale);
|
||||
view.setScaleY(newScale);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the clipping of a view
|
||||
*
|
||||
@@ -201,12 +226,12 @@ public class StackScrollState {
|
||||
child.setClipBounds(mClipRect);
|
||||
}
|
||||
|
||||
public void performSpeedBumpAnimation(int i, SpeedBumpView speedBump, ViewState state,
|
||||
public void performSpeedBumpAnimation(int i, SpeedBumpView speedBump, StackViewState state,
|
||||
long delay) {
|
||||
View nextChild = getNextChildNotGone(i);
|
||||
if (nextChild != null) {
|
||||
float lineEnd = state.yTranslation + state.height / 2;
|
||||
ViewState nextState = getViewStateForView(nextChild);
|
||||
StackViewState nextState = getViewStateForView(nextChild);
|
||||
boolean startIsAboveNext = nextState.yTranslation > lineEnd;
|
||||
speedBump.animateDivider(startIsAboveNext, delay, null /* onFinishedRunnable */);
|
||||
}
|
||||
@@ -223,53 +248,4 @@ public class StackScrollState {
|
||||
return null;
|
||||
}
|
||||
|
||||
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;
|
||||
/** The view isn't layouted at all. */
|
||||
public static final int LOCATION_GONE = 0x40;
|
||||
|
||||
float alpha;
|
||||
float yTranslation;
|
||||
float zTranslation;
|
||||
int height;
|
||||
boolean gone;
|
||||
float scale;
|
||||
boolean dimmed;
|
||||
boolean dark;
|
||||
boolean hideSensitive;
|
||||
boolean belowSpeedBump;
|
||||
|
||||
/**
|
||||
* The amount which the view should be clipped from the top. This is calculated to
|
||||
* perceive consistent shadows.
|
||||
*/
|
||||
int clipTopAmount;
|
||||
|
||||
/**
|
||||
* How much does the child overlap with the previous view on the top? Can be used for
|
||||
* a clipping optimization
|
||||
*/
|
||||
int topOverLap;
|
||||
|
||||
/**
|
||||
* The index of the view, only accounting for views not equal to GONE
|
||||
*/
|
||||
int notGoneIndex;
|
||||
|
||||
/**
|
||||
* The location this view is currently rendered at.
|
||||
*
|
||||
* <p>See <code>LOCATION_</code> flags.</p>
|
||||
*/
|
||||
int location;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -113,13 +113,13 @@ public class StackStateAnimator {
|
||||
for (int i = 0; i < childCount; i++) {
|
||||
final ExpandableView child = (ExpandableView) mHostLayout.getChildAt(i);
|
||||
|
||||
StackScrollState.ViewState viewState = finalState.getViewStateForView(child);
|
||||
StackViewState viewState = finalState.getViewStateForView(child);
|
||||
if (viewState == null || child.getVisibility() == View.GONE) {
|
||||
continue;
|
||||
}
|
||||
|
||||
child.setClipBounds(null);
|
||||
startAnimations(child, viewState, finalState, i);
|
||||
startStackAnimations(child, viewState, finalState, i, -1 /* fixedDelay */);
|
||||
}
|
||||
if (!isRunning()) {
|
||||
// no child has preformed any animation, lets finish
|
||||
@@ -134,7 +134,7 @@ public class StackStateAnimator {
|
||||
for (int i = childCount - 1; i >= 0; i--) {
|
||||
final ExpandableView child = (ExpandableView) mHostLayout.getChildAt(i);
|
||||
|
||||
StackScrollState.ViewState viewState = finalState.getViewStateForView(child);
|
||||
StackViewState viewState = finalState.getViewStateForView(child);
|
||||
if (viewState == null || child.getVisibility() == View.GONE) {
|
||||
continue;
|
||||
}
|
||||
@@ -145,18 +145,29 @@ public class StackStateAnimator {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Start an animation to the given viewState
|
||||
*/
|
||||
private void startAnimations(final ExpandableView child, StackScrollState.ViewState viewState,
|
||||
StackScrollState finalState, int i) {
|
||||
int childVisibility = child.getVisibility();
|
||||
boolean wasVisible = childVisibility == View.VISIBLE;
|
||||
final float alpha = viewState.alpha;
|
||||
if (!wasVisible && alpha != 0 && !viewState.gone) {
|
||||
child.setVisibility(View.VISIBLE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Start an animation to the given {@link StackViewState}.
|
||||
*
|
||||
* @param child the child to start the animation on
|
||||
* @param viewState the {@link StackViewState} of the view to animate to
|
||||
* @param finalState the final state after the animation
|
||||
* @param i the index of the view; only relevant if the view is the speed bump and is
|
||||
* ignored otherwise
|
||||
* @param fixedDelay a fixed delay if desired or -1 if the delay should be calculated
|
||||
*/
|
||||
public void startStackAnimations(final ExpandableView child, StackViewState viewState,
|
||||
StackScrollState finalState, int i, long fixedDelay) {
|
||||
final float alpha = viewState.alpha;
|
||||
boolean wasAdded = mNewAddChildren.contains(child);
|
||||
long duration = mCurrentLength;
|
||||
if (wasAdded && mAnimationFilter.hasGoToFullShadeEvent) {
|
||||
child.setTranslationY(child.getTranslationY() + mGoToFullShadeAppearingTranslation);
|
||||
float longerDurationFactor = viewState.notGoneIndex - mCurrentLastNotAddedIndex;
|
||||
longerDurationFactor = (float) Math.pow(longerDurationFactor, 0.7f);
|
||||
duration = ANIMATION_DURATION_APPEAR_DISAPPEAR + 50 +
|
||||
(long) (100 * longerDurationFactor);
|
||||
}
|
||||
boolean yTranslationChanging = child.getTranslationY() != viewState.yTranslation;
|
||||
boolean zTranslationChanging = child.getTranslationZ() != viewState.zTranslation;
|
||||
boolean scaleChanging = child.getScaleX() != viewState.scale;
|
||||
@@ -164,94 +175,40 @@ public class StackStateAnimator {
|
||||
boolean heightChanging = viewState.height != child.getActualHeight();
|
||||
boolean darkChanging = viewState.dark != child.isDark();
|
||||
boolean topInsetChanging = viewState.clipTopAmount != child.getClipTopAmount();
|
||||
boolean wasAdded = mNewAddChildren.contains(child);
|
||||
boolean hasDelays = mAnimationFilter.hasDelays;
|
||||
boolean isDelayRelevant = yTranslationChanging || zTranslationChanging || scaleChanging ||
|
||||
alphaChanging || heightChanging || topInsetChanging || darkChanging;
|
||||
boolean noAnimation = wasAdded;
|
||||
long delay = 0;
|
||||
long duration = mCurrentLength;
|
||||
if (hasDelays && isDelayRelevant || wasAdded) {
|
||||
if (fixedDelay != -1) {
|
||||
delay = fixedDelay;
|
||||
} else if (hasDelays && isDelayRelevant || wasAdded) {
|
||||
delay = mCurrentAdditionalDelay + calculateChildAnimationDelay(viewState, finalState);
|
||||
}
|
||||
|
||||
if (wasAdded && mAnimationFilter.hasGoToFullShadeEvent) {
|
||||
child.setTranslationY(child.getTranslationY() + mGoToFullShadeAppearingTranslation);
|
||||
yTranslationChanging = true;
|
||||
float longerDurationFactor = viewState.notGoneIndex - mCurrentLastNotAddedIndex;
|
||||
longerDurationFactor = (float) Math.pow(longerDurationFactor, 0.7f);
|
||||
duration = ANIMATION_DURATION_APPEAR_DISAPPEAR + 50 +
|
||||
(long) (100 * longerDurationFactor);
|
||||
}
|
||||
|
||||
// start translationY animation
|
||||
if (yTranslationChanging) {
|
||||
if (noAnimation && !mAnimationFilter.hasGoToFullShadeEvent) {
|
||||
child.setTranslationY(viewState.yTranslation);
|
||||
} else {
|
||||
startYTranslationAnimation(child, viewState, duration, delay);
|
||||
}
|
||||
}
|
||||
|
||||
// start translationZ animation
|
||||
if (zTranslationChanging) {
|
||||
if (noAnimation) {
|
||||
child.setTranslationZ(viewState.zTranslation);
|
||||
} else {
|
||||
startZTranslationAnimation(child, viewState, duration, delay);
|
||||
}
|
||||
}
|
||||
|
||||
// start scale animation
|
||||
if (scaleChanging) {
|
||||
if (noAnimation) {
|
||||
child.setScaleX(viewState.scale);
|
||||
child.setScaleY(viewState.scale);
|
||||
} else {
|
||||
startScaleAnimation(child, viewState, duration);
|
||||
}
|
||||
}
|
||||
|
||||
// start alpha animation
|
||||
if (alphaChanging && child.getTranslationX() == 0) {
|
||||
if (noAnimation) {
|
||||
child.setAlpha(viewState.alpha);
|
||||
} else {
|
||||
startAlphaAnimation(child, viewState, duration, delay);
|
||||
}
|
||||
}
|
||||
startViewAnimations(child, viewState, delay, duration);
|
||||
|
||||
// start height animation
|
||||
if (heightChanging && child.getActualHeight() != 0) {
|
||||
if (noAnimation) {
|
||||
child.setActualHeight(viewState.height, false);
|
||||
} else {
|
||||
startHeightAnimation(child, viewState, duration, delay);
|
||||
}
|
||||
startHeightAnimation(child, viewState, duration, delay);
|
||||
}
|
||||
|
||||
// start top inset animation
|
||||
if (topInsetChanging) {
|
||||
if (noAnimation) {
|
||||
child.setClipTopAmount(viewState.clipTopAmount);
|
||||
} else {
|
||||
startInsetAnimation(child, viewState, duration, delay);
|
||||
}
|
||||
startInsetAnimation(child, viewState, duration, delay);
|
||||
}
|
||||
|
||||
// start dimmed animation
|
||||
child.setDimmed(viewState.dimmed, mAnimationFilter.animateDimmed && !wasAdded
|
||||
&& !noAnimation);
|
||||
child.setDimmed(viewState.dimmed, mAnimationFilter.animateDimmed);
|
||||
|
||||
// start dark animation
|
||||
child.setDark(viewState.dark, mAnimationFilter.animateDark && !noAnimation, delay);
|
||||
child.setDark(viewState.dark, mAnimationFilter.animateDark, delay);
|
||||
|
||||
// apply speed bump state
|
||||
child.setBelowSpeedBump(viewState.belowSpeedBump);
|
||||
|
||||
// start hiding sensitive animation
|
||||
child.setHideSensitive(viewState.hideSensitive, mAnimationFilter.animateHideSensitive &&
|
||||
!wasAdded && !noAnimation, delay, duration);
|
||||
child.setHideSensitive(viewState.hideSensitive, mAnimationFilter.animateHideSensitive,
|
||||
delay, duration);
|
||||
|
||||
if (wasAdded) {
|
||||
child.performAddAnimation(delay, mCurrentLength);
|
||||
@@ -262,7 +219,48 @@ public class StackStateAnimator {
|
||||
}
|
||||
}
|
||||
|
||||
private long calculateChildAnimationDelay(StackScrollState.ViewState viewState,
|
||||
/**
|
||||
* Start an animation to a new {@link ViewState}.
|
||||
*
|
||||
* @param child the child to start the animation on
|
||||
* @param viewState the {@link StackViewState} of the view to animate to
|
||||
* @param delay a fixed delay
|
||||
* @param duration the duration of the animation
|
||||
*/
|
||||
public void startViewAnimations(View child, ViewState viewState, long delay, long duration) {
|
||||
boolean wasVisible = child.getVisibility() == View.VISIBLE;
|
||||
final float alpha = viewState.alpha;
|
||||
if (!wasVisible && alpha != 0 && !viewState.gone) {
|
||||
child.setVisibility(View.VISIBLE);
|
||||
}
|
||||
boolean yTranslationChanging = child.getTranslationY() != viewState.yTranslation;
|
||||
boolean zTranslationChanging = child.getTranslationZ() != viewState.zTranslation;
|
||||
boolean scaleChanging = child.getScaleX() != viewState.scale;
|
||||
float childAlpha = child.getVisibility() == View.INVISIBLE ? 0.0f : child.getAlpha();
|
||||
boolean alphaChanging = viewState.alpha != childAlpha;
|
||||
|
||||
// start translationY animation
|
||||
if (yTranslationChanging) {
|
||||
startYTranslationAnimation(child, viewState, duration, delay);
|
||||
}
|
||||
|
||||
// start translationZ animation
|
||||
if (zTranslationChanging) {
|
||||
startZTranslationAnimation(child, viewState, duration, delay);
|
||||
}
|
||||
|
||||
// start scale animation
|
||||
if (scaleChanging) {
|
||||
startScaleAnimation(child, viewState, duration);
|
||||
}
|
||||
|
||||
// start alpha animation
|
||||
if (alphaChanging && child.getTranslationX() == 0) {
|
||||
startAlphaAnimation(child, viewState, duration, delay);
|
||||
}
|
||||
}
|
||||
|
||||
private long calculateChildAnimationDelay(StackViewState viewState,
|
||||
StackScrollState finalState) {
|
||||
if (mAnimationFilter.hasDarkEvent) {
|
||||
return calculateDelayDark(viewState);
|
||||
@@ -314,7 +312,7 @@ public class StackStateAnimator {
|
||||
return minDelay;
|
||||
}
|
||||
|
||||
private long calculateDelayDark(StackScrollState.ViewState viewState) {
|
||||
private long calculateDelayDark(StackViewState viewState) {
|
||||
int referenceIndex;
|
||||
if (mAnimationFilter.darkAnimationOriginIndex ==
|
||||
NotificationStackScrollLayout.AnimationEvent.DARK_ANIMATION_ORIGIN_INDEX_ABOVE) {
|
||||
@@ -328,14 +326,14 @@ public class StackStateAnimator {
|
||||
return Math.abs(referenceIndex - viewState.notGoneIndex) * ANIMATION_DELAY_PER_ELEMENT_DARK;
|
||||
}
|
||||
|
||||
private long calculateDelayGoToFullShade(StackScrollState.ViewState viewState) {
|
||||
private long calculateDelayGoToFullShade(StackViewState viewState) {
|
||||
float index = viewState.notGoneIndex;
|
||||
index = (float) Math.pow(index, 0.7f);
|
||||
return (long) (index * ANIMATION_DELAY_PER_ELEMENT_GO_TO_FULL_SHADE);
|
||||
}
|
||||
|
||||
private void startHeightAnimation(final ExpandableView child,
|
||||
StackScrollState.ViewState viewState, long duration, long delay) {
|
||||
StackViewState viewState, long duration, long delay) {
|
||||
Integer previousStartValue = getChildTag(child, TAG_START_HEIGHT);
|
||||
Integer previousEndValue = getChildTag(child, TAG_END_HEIGHT);
|
||||
int newEndValue = viewState.height;
|
||||
@@ -394,7 +392,7 @@ public class StackStateAnimator {
|
||||
}
|
||||
|
||||
private void startInsetAnimation(final ExpandableView child,
|
||||
StackScrollState.ViewState viewState, long duration, long delay) {
|
||||
StackViewState viewState, long duration, long delay) {
|
||||
Integer previousStartValue = getChildTag(child, TAG_START_TOP_INSET);
|
||||
Integer previousEndValue = getChildTag(child, TAG_END_TOP_INSET);
|
||||
int newEndValue = viewState.clipTopAmount;
|
||||
@@ -451,8 +449,8 @@ public class StackStateAnimator {
|
||||
child.setTag(TAG_END_TOP_INSET, newEndValue);
|
||||
}
|
||||
|
||||
private void startAlphaAnimation(final ExpandableView child,
|
||||
final StackScrollState.ViewState viewState, long duration, long delay) {
|
||||
private void startAlphaAnimation(final View child,
|
||||
final ViewState viewState, long duration, long delay) {
|
||||
Float previousStartValue = getChildTag(child,TAG_START_ALPHA);
|
||||
Float previousEndValue = getChildTag(child,TAG_END_ALPHA);
|
||||
final float newEndValue = viewState.alpha;
|
||||
@@ -525,8 +523,8 @@ public class StackStateAnimator {
|
||||
child.setTag(TAG_END_ALPHA, newEndValue);
|
||||
}
|
||||
|
||||
private void startZTranslationAnimation(final ExpandableView child,
|
||||
final StackScrollState.ViewState viewState, long duration, long delay) {
|
||||
private void startZTranslationAnimation(final View child,
|
||||
final ViewState viewState, long duration, long delay) {
|
||||
Float previousStartValue = getChildTag(child,TAG_START_TRANSLATION_Z);
|
||||
Float previousEndValue = getChildTag(child,TAG_END_TRANSLATION_Z);
|
||||
float newEndValue = viewState.zTranslation;
|
||||
@@ -577,8 +575,8 @@ public class StackStateAnimator {
|
||||
child.setTag(TAG_END_TRANSLATION_Z, newEndValue);
|
||||
}
|
||||
|
||||
private void startYTranslationAnimation(final ExpandableView child,
|
||||
StackScrollState.ViewState viewState, long duration, long delay) {
|
||||
private void startYTranslationAnimation(final View child,
|
||||
ViewState viewState, long duration, long delay) {
|
||||
Float previousStartValue = getChildTag(child,TAG_START_TRANSLATION_Y);
|
||||
Float previousEndValue = getChildTag(child,TAG_END_TRANSLATION_Y);
|
||||
float newEndValue = viewState.yTranslation;
|
||||
@@ -630,8 +628,8 @@ public class StackStateAnimator {
|
||||
child.setTag(TAG_END_TRANSLATION_Y, newEndValue);
|
||||
}
|
||||
|
||||
private void startScaleAnimation(final ExpandableView child,
|
||||
StackScrollState.ViewState viewState, long duration) {
|
||||
private void startScaleAnimation(final View child,
|
||||
ViewState viewState, long duration) {
|
||||
Float previousStartValue = getChildTag(child, TAG_START_SCALE);
|
||||
Float previousEndValue = getChildTag(child, TAG_END_SCALE);
|
||||
float newEndValue = viewState.scale;
|
||||
@@ -765,7 +763,7 @@ public class StackStateAnimator {
|
||||
NotificationStackScrollLayout.AnimationEvent.ANIMATION_TYPE_ADD) {
|
||||
|
||||
// This item is added, initialize it's properties.
|
||||
StackScrollState.ViewState viewState = finalState
|
||||
StackViewState viewState = finalState
|
||||
.getViewStateForView(changingView);
|
||||
if (viewState == null) {
|
||||
// The position for this child was never generated, let's continue.
|
||||
@@ -776,10 +774,7 @@ public class StackStateAnimator {
|
||||
finalState.removeViewStateForView(changingView);
|
||||
continue;
|
||||
}
|
||||
changingView.setAlpha(viewState.alpha);
|
||||
changingView.setTranslationY(viewState.yTranslation);
|
||||
changingView.setTranslationZ(viewState.zTranslation);
|
||||
changingView.setActualHeight(viewState.height, false);
|
||||
finalState.applyState(changingView, viewState);
|
||||
mNewAddChildren.add(changingView);
|
||||
|
||||
} else if (event.animationType ==
|
||||
@@ -791,7 +786,7 @@ public class StackStateAnimator {
|
||||
|
||||
// Find the amount to translate up. This is needed in order to understand the
|
||||
// direction of the remove animation (either downwards or upwards)
|
||||
StackScrollState.ViewState viewState = finalState
|
||||
StackViewState viewState = finalState
|
||||
.getViewStateForView(event.viewAfterChangingView);
|
||||
int actualHeight = changingView.getActualHeight();
|
||||
// upwards by default
|
||||
@@ -813,7 +808,7 @@ public class StackStateAnimator {
|
||||
mHostLayout.getOverlay().remove(changingView);
|
||||
}
|
||||
});
|
||||
} else if (event.animationType ==
|
||||
} else if (event.animationType ==
|
||||
NotificationStackScrollLayout.AnimationEvent.ANIMATION_TYPE_REMOVE_SWIPED_OUT) {
|
||||
// A race condition can trigger the view to be added to the overlay even though
|
||||
// it is swiped out. So let's remove it
|
||||
|
||||
@@ -0,0 +1,86 @@
|
||||
/*
|
||||
* Copyright (C) 2015 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License
|
||||
*/
|
||||
|
||||
package com.android.systemui.statusbar.stack;
|
||||
|
||||
import android.view.View;
|
||||
|
||||
import com.android.systemui.statusbar.ExpandableView;
|
||||
|
||||
/**
|
||||
* A state of an expandable view
|
||||
*/
|
||||
public class StackViewState extends 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;
|
||||
/** The view isn't layouted at all. */
|
||||
public static final int LOCATION_GONE = 0x40;
|
||||
|
||||
public int height;
|
||||
public boolean dimmed;
|
||||
public boolean dark;
|
||||
public boolean hideSensitive;
|
||||
public boolean belowSpeedBump;
|
||||
|
||||
/**
|
||||
* The amount which the view should be clipped from the top. This is calculated to
|
||||
* perceive consistent shadows.
|
||||
*/
|
||||
public int clipTopAmount;
|
||||
|
||||
/**
|
||||
* How much does the child overlap with the previous view on the top? Can be used for
|
||||
* a clipping optimization
|
||||
*/
|
||||
public int topOverLap;
|
||||
|
||||
/**
|
||||
* The index of the view, only accounting for views not equal to GONE
|
||||
*/
|
||||
public int notGoneIndex;
|
||||
|
||||
/**
|
||||
* The location this view is currently rendered at.
|
||||
*
|
||||
* <p>See <code>LOCATION_</code> flags.</p>
|
||||
*/
|
||||
public int location;
|
||||
|
||||
@Override
|
||||
public void copyFrom(ViewState viewState) {
|
||||
super.copyFrom(viewState);
|
||||
if (viewState instanceof StackViewState) {
|
||||
StackViewState svs = (StackViewState) viewState;
|
||||
height = svs.height;
|
||||
dimmed = svs.dimmed;
|
||||
dark = svs.dark;
|
||||
hideSensitive = svs.hideSensitive;
|
||||
belowSpeedBump = svs.belowSpeedBump;
|
||||
clipTopAmount = svs.clipTopAmount;
|
||||
topOverLap = svs.topOverLap;
|
||||
notGoneIndex = svs.notGoneIndex;
|
||||
location = svs.location;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Copyright (C) 2015 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License
|
||||
*/
|
||||
|
||||
package com.android.systemui.statusbar.stack;
|
||||
|
||||
import android.view.View;
|
||||
|
||||
/**
|
||||
* A state of a view. This can be used to apply a set of view properties to a view with
|
||||
* {@link com.android.systemui.statusbar.stack.StackScrollState} or start animations with
|
||||
* {@link com.android.systemui.statusbar.stack.StackStateAnimator}.
|
||||
*/
|
||||
public class ViewState {
|
||||
|
||||
public float alpha;
|
||||
public float yTranslation;
|
||||
public float zTranslation;
|
||||
public boolean gone;
|
||||
public float scale;
|
||||
|
||||
public void copyFrom(ViewState viewState) {
|
||||
alpha = viewState.alpha;
|
||||
yTranslation = viewState.yTranslation;
|
||||
zTranslation = viewState.zTranslation;
|
||||
gone = viewState.gone;
|
||||
scale = viewState.scale;
|
||||
}
|
||||
|
||||
public void initFrom(View view) {
|
||||
alpha = view.getVisibility() == View.INVISIBLE ? 0.0f : view.getAlpha();
|
||||
yTranslation = view.getTranslationY();
|
||||
zTranslation = view.getTranslationZ();
|
||||
gone = view.getVisibility() == View.GONE;
|
||||
scale = view.getScaleX();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user