/** Update the visible children on the state. */ private void updateVisibleChildren( StackScrollState resultState, StackScrollAlgorithmState state) { Log.d(TAG, "updateVisibleChildren: "); ViewGroup hostView = resultState.getHostView(); 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) { notGoneIndex = updateNotGoneIndex(resultState, state, notGoneIndex, v); if (v instanceof ExpandableNotificationRow) { ExpandableNotificationRow row = (ExpandableNotificationRow) v; // handle the notgoneIndex for the children as well List<ExpandableNotificationRow> children = row.getNotificationChildren(); if (row.areChildrenExpanded() && children != null) { for (ExpandableNotificationRow childRow : children) { if (childRow.getVisibility() != View.GONE) { StackViewState childState = resultState.getViewStateForView(childRow); childState.notGoneIndex = notGoneIndex; notGoneIndex++; } } } } } } }
private void updateClipping( StackScrollState resultState, StackScrollAlgorithmState algorithmState, AmbientState ambientState) { Log.d(TAG, "updateClipping: "); boolean dismissAllInProgress = ambientState.isDismissAllInProgress(); float previousNotificationEnd = 0; float previousNotificationStart = 0; boolean previousNotificationIsSwiped = false; int childCount = algorithmState.visibleChildren.size(); for (int i = 0; i < childCount; i++) { ExpandableView child = algorithmState.visibleChildren.get(i); 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 float newNotificationEnd = newYTranslation + newHeight; float clipHeight; if (previousNotificationIsSwiped) { // When the previous notification is swiped, we don't clip the content to the // bottom of it. clipHeight = newHeight; } else { clipHeight = newNotificationEnd - previousNotificationEnd; clipHeight = Math.max(0.0f, clipHeight); if (clipHeight != 0.0f) { // In the unlocked shade we have to clip a little bit higher because of the rounded // corners of the notifications, but only if we are not fully overlapped by // the top card. float clippingCorrection = state.dimmed ? 0 : mRoundedRectCornerRadius * state.scale; clipHeight += clippingCorrection; } } updateChildClippingAndBackground( state, newHeight, clipHeight, newHeight - (previousNotificationStart - newYTranslation)); if (dismissAllInProgress) { state.clipTopAmount = Math.max(child.getMinClipTopAmount(), state.clipTopAmount); } if (!child.isTransparent()) { // Only update the previous values if we are not transparent, // otherwise we would clip to a transparent view. if ((dismissAllInProgress && canChildBeDismissed(child))) { previousNotificationIsSwiped = true; } else { previousNotificationIsSwiped = ambientState.getDraggedViews().contains(child); previousNotificationEnd = newNotificationEnd; previousNotificationStart = newYTranslation + state.clipTopAmount * state.scale; } } } }
private void updateFirstChildMaxSizeToMaxHeight() { Log.d(TAG, "updateFirstChildMaxSizeToMaxHeight: "); // We are expanding the shade, expand it to its full height. if (!isMaxSizeInitialized(mFirstChildWhileExpanding)) { // This child was not layouted yet, wait for a layout pass mFirstChildWhileExpanding.addOnLayoutChangeListener( new View.OnLayoutChangeListener() { @Override public void onLayoutChange( View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) { if (mFirstChildWhileExpanding != null) { mFirstChildMaxHeight = getMaxAllowedChildHeight(mFirstChildWhileExpanding, null); } else { mFirstChildMaxHeight = 0; } v.removeOnLayoutChangeListener(this); } }); } else { mFirstChildMaxHeight = getMaxAllowedChildHeight(mFirstChildWhileExpanding, null); } }
private int getMaxAllowedChildHeight(View child, AmbientState ambientState) { Log.d(TAG, "getMaxAllowedChildHeight: "); if (child instanceof ExpandableNotificationRow) { ExpandableNotificationRow row = (ExpandableNotificationRow) child; if (ambientState == null && row.isHeadsUp() || ambientState != null && ambientState.getTopHeadsUpEntry() == child) { int extraSize = row.getIntrinsicHeight() - row.getHeadsUpHeight(); return mCollapsedSize + extraSize; } return row.getIntrinsicHeight(); } else if (child instanceof ExpandableView) { ExpandableView expandableView = (ExpandableView) child; return expandableView.getIntrinsicHeight(); } return child == null ? mCollapsedSize : child.getHeight(); }
private boolean isMaxSizeInitialized(ExpandableView child) { Log.d(TAG, "isMaxSizeInitialized: "); if (child instanceof ExpandableNotificationRow) { ExpandableNotificationRow row = (ExpandableNotificationRow) child; return row.isMaxExpandHeightInitialized(); } return child == null || child.getWidth() != 0; }
public void onReset(ExpandableView view) { Log.d(TAG, "onReset: "); if (view.equals(mFirstChildWhileExpanding)) { updateFirstChildMaxSizeToMaxHeight(); } }