private void updateStateForChildFullyInBottomStack( StackScrollAlgorithmState algorithmState, float transitioningPositionStart, StackViewState childViewState, int childHeight, AmbientState ambientState) { Log.d(TAG, "updateStateForChildFullyInBottomStack: "); float currentYPosition; algorithmState.itemsInBottomStack += 1.0f; if (algorithmState.itemsInBottomStack < MAX_ITEMS_IN_BOTTOM_STACK) { // We are visually entering the bottom stack currentYPosition = transitioningPositionStart + mBottomStackIndentationFunctor.getValue(algorithmState.itemsInBottomStack) - mPaddingBetweenElements; childViewState.location = StackViewState.LOCATION_BOTTOM_STACK_PEEKING; } else { // we are fully inside the stack if (algorithmState.itemsInBottomStack > MAX_ITEMS_IN_BOTTOM_STACK + 2) { childViewState.alpha = 0.0f; } else if (algorithmState.itemsInBottomStack > MAX_ITEMS_IN_BOTTOM_STACK + 1) { childViewState.alpha = 1.0f - algorithmState.partialInBottom; } childViewState.location = StackViewState.LOCATION_BOTTOM_STACK_HIDDEN; currentYPosition = ambientState.getInnerHeight(); } childViewState.yTranslation = currentYPosition - childHeight; clampPositionToTopStackEnd(childViewState, childHeight); }
private void updateStateForChildTransitioningInBottom( StackScrollAlgorithmState algorithmState, float transitioningPositionStart, float bottomPeakStart, float currentYPosition, StackViewState childViewState, int childHeight) { Log.d(TAG, "updateStateForChildTransitioningInBottom: "); // This is the transitioning element on top of bottom stack, calculate how far we are in. algorithmState.partialInBottom = 1.0f - ((transitioningPositionStart - currentYPosition) / (childHeight + mPaddingBetweenElements)); // the offset starting at the transitionPosition of the bottom stack float offset = mBottomStackIndentationFunctor.getValue(algorithmState.partialInBottom); algorithmState.itemsInBottomStack += algorithmState.partialInBottom; int newHeight = childHeight; if (childHeight > mCollapsedSize && mIsSmallScreen) { newHeight = (int) Math.max( Math.min( transitioningPositionStart + offset - mPaddingBetweenElements - currentYPosition, childHeight), mCollapsedSize); childViewState.height = newHeight; } childViewState.yTranslation = transitioningPositionStart + offset - newHeight - mPaddingBetweenElements; // We want at least to be at the end of the top stack when collapsing clampPositionToTopStackEnd(childViewState, newHeight); childViewState.location = StackViewState.LOCATION_MAIN_AREA; }
public void getStackScrollState(AmbientState ambientState, StackScrollState resultState) { // The state of the local variables are saved in an algorithmState to easily subdivide it // into multiple phases. Log.d(TAG, "getStackScrollState: "); StackScrollAlgorithmState algorithmState = mTempAlgorithmState; // First we reset the view states to their default values. resultState.resetViewStates(); algorithmState.itemsInTopStack = 0.0f; algorithmState.partialInTop = 0.0f; algorithmState.lastTopStackIndex = 0; algorithmState.scrolledPixelsTop = 0; algorithmState.itemsInBottomStack = 0.0f; algorithmState.partialInBottom = 0.0f; float bottomOverScroll = ambientState.getOverScrollAmount(false /* onTop */); int scrollY = ambientState.getScrollY(); // Due to the overScroller, the stackscroller can have negative scroll state. This is // already accounted for by the top padding and doesn't need an additional adaption scrollY = Math.max(0, scrollY); algorithmState.scrollY = (int) (scrollY + mCollapsedSize + bottomOverScroll); updateVisibleChildren(resultState, algorithmState); // Phase 1: findNumberOfItemsInTopStackAndUpdateState(resultState, algorithmState, ambientState); // Phase 2: updatePositionsForState(resultState, algorithmState, ambientState); // Phase 3: updateZValuesForState(resultState, algorithmState); handleDraggedViews(ambientState, resultState, algorithmState); updateDimmedActivatedHideSensitive(ambientState, resultState, algorithmState); updateClipping(resultState, algorithmState, ambientState); updateSpeedBumpState(resultState, algorithmState, ambientState.getSpeedBumpIndex()); getNotificationChildrenStates(resultState, algorithmState); }
/** * Find the number of items in the top stack and update the result state if needed. * * @param resultState The result state to update if a height change of an child occurs * @param algorithmState The state in which the current pass of the algorithm is currently in */ private void findNumberOfItemsInTopStackAndUpdateState( StackScrollState resultState, StackScrollAlgorithmState algorithmState, AmbientState ambientState) { Log.d(TAG, "findNumberOfItemsInTopStackAndUpdateState: "); // The y Position if the element would be in a regular scrollView float yPositionInScrollView = 0.0f; int childCount = algorithmState.visibleChildren.size(); // find the number of elements in the top stack. for (int i = 0; i < childCount; i++) { ExpandableView child = algorithmState.visibleChildren.get(i); StackViewState childViewState = resultState.getViewStateForView(child); int childHeight = getMaxAllowedChildHeight(child, ambientState); float yPositionInScrollViewAfterElement = yPositionInScrollView + childHeight + mPaddingBetweenElements; if (yPositionInScrollView < algorithmState.scrollY) { if (i == 0 && algorithmState.scrollY <= mCollapsedSize) { // The starting position of the bottom stack peek int bottomPeekStart = ambientState.getInnerHeight() - mBottomStackPeekSize - mCollapseSecondCardPadding; // Collapse and expand the first child while the shade is being expanded float maxHeight = mIsExpansionChanging && child == mFirstChildWhileExpanding ? mFirstChildMaxHeight : childHeight; childViewState.height = (int) Math.max(Math.min(bottomPeekStart, maxHeight), mCollapsedSize); algorithmState.itemsInTopStack = 1.0f; } else if (yPositionInScrollViewAfterElement < algorithmState.scrollY) { // According to the regular scroll view we are fully off screen algorithmState.itemsInTopStack += 1.0f; if (i == 0) { childViewState.height = mCollapsedSize; } } else { // According to the regular scroll view we are partially off screen // How much did we scroll into this child algorithmState.scrolledPixelsTop = algorithmState.scrollY - yPositionInScrollView; algorithmState.partialInTop = (algorithmState.scrolledPixelsTop) / (childHeight + mPaddingBetweenElements); // Our element can be expanded, so this can get negative algorithmState.partialInTop = Math.max(0.0f, algorithmState.partialInTop); algorithmState.itemsInTopStack += algorithmState.partialInTop; if (i == 0) { // If it is expanded we have to collapse it to a new size float newSize = yPositionInScrollViewAfterElement - mPaddingBetweenElements - algorithmState.scrollY + mCollapsedSize; newSize = Math.max(mCollapsedSize, newSize); algorithmState.itemsInTopStack = 1.0f; childViewState.height = (int) newSize; } algorithmState.lastTopStackIndex = i; break; } } else { algorithmState.lastTopStackIndex = i - 1; // We are already past the stack so we can end the loop break; } yPositionInScrollView = yPositionInScrollViewAfterElement; } }