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; } }