Search in sources :

Example 11 with ExpandableNotificationRow

use of com.android.systemui.statusbar.ExpandableNotificationRow in project platform_frameworks_base by android.

the class StackStateAnimator method startStackAnimations.

/**
     * 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) {
    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 alphaChanging = viewState.alpha != child.getAlpha();
    boolean heightChanging = viewState.height != child.getActualHeight();
    boolean shadowAlphaChanging = viewState.shadowAlpha != child.getShadowAlpha();
    boolean darkChanging = viewState.dark != child.isDark();
    boolean topInsetChanging = viewState.clipTopAmount != child.getClipTopAmount();
    boolean hasDelays = mAnimationFilter.hasDelays;
    boolean isDelayRelevant = yTranslationChanging || zTranslationChanging || alphaChanging || heightChanging || topInsetChanging || darkChanging || shadowAlphaChanging;
    long delay = 0;
    if (fixedDelay != -1) {
        delay = fixedDelay;
    } else if (hasDelays && isDelayRelevant || wasAdded) {
        delay = mCurrentAdditionalDelay + calculateChildAnimationDelay(viewState, finalState);
    }
    startViewAnimations(child, viewState, delay, duration);
    // start height animation
    if (heightChanging) {
        startHeightAnimation(child, viewState, duration, delay);
    } else {
        abortAnimation(child, TAG_ANIMATOR_HEIGHT);
    }
    // start shadow alpha animation
    if (shadowAlphaChanging) {
        startShadowAlphaAnimation(child, viewState, duration, delay);
    } else {
        abortAnimation(child, TAG_ANIMATOR_SHADOW_ALPHA);
    }
    // start top inset animation
    if (topInsetChanging) {
        startInsetAnimation(child, viewState, duration, delay);
    } else {
        abortAnimation(child, TAG_ANIMATOR_TOP_INSET);
    }
    // start dimmed animation
    child.setDimmed(viewState.dimmed, mAnimationFilter.animateDimmed);
    // apply speed bump state
    child.setBelowSpeedBump(viewState.belowSpeedBump);
    // start hiding sensitive animation
    child.setHideSensitive(viewState.hideSensitive, mAnimationFilter.animateHideSensitive, delay, duration);
    // start dark animation
    child.setDark(viewState.dark, mAnimationFilter.animateDark, delay);
    if (wasAdded) {
        child.performAddAnimation(delay, mCurrentLength);
    }
    if (child instanceof ExpandableNotificationRow) {
        ExpandableNotificationRow row = (ExpandableNotificationRow) child;
        row.startChildAnimation(finalState, this, delay, duration);
    }
}
Also used : ExpandableNotificationRow(com.android.systemui.statusbar.ExpandableNotificationRow)

Example 12 with ExpandableNotificationRow

use of com.android.systemui.statusbar.ExpandableNotificationRow in project platform_frameworks_base by android.

the class StackStateAnimator method processAnimationEvents.

/**
     * Process the animationEvents for a new animation
     *
     * @param animationEvents the animation events for the animation to perform
     * @param finalState the final state to animate to
     */
private void processAnimationEvents(ArrayList<NotificationStackScrollLayout.AnimationEvent> animationEvents, StackScrollState finalState) {
    for (NotificationStackScrollLayout.AnimationEvent event : animationEvents) {
        final ExpandableView changingView = (ExpandableView) event.changingView;
        if (event.animationType == NotificationStackScrollLayout.AnimationEvent.ANIMATION_TYPE_ADD) {
            // This item is added, initialize it's properties.
            StackViewState viewState = finalState.getViewStateForView(changingView);
            if (viewState == null) {
                // The position for this child was never generated, let's continue.
                continue;
            }
            finalState.applyState(changingView, viewState);
            mNewAddChildren.add(changingView);
        } else if (event.animationType == NotificationStackScrollLayout.AnimationEvent.ANIMATION_TYPE_REMOVE) {
            if (changingView.getVisibility() == View.GONE) {
                removeFromOverlay(changingView);
                continue;
            }
            // Find the amount to translate up. This is needed in order to understand the
            // direction of the remove animation (either downwards or upwards)
            StackViewState viewState = finalState.getViewStateForView(event.viewAfterChangingView);
            int actualHeight = changingView.getActualHeight();
            // upwards by default
            float translationDirection = -1.0f;
            if (viewState != null) {
                // there was a view after this one, Approximate the distance the next child
                // travelled
                translationDirection = ((viewState.yTranslation - (changingView.getTranslationY() + actualHeight / 2.0f)) * 2 / actualHeight);
                translationDirection = Math.max(Math.min(translationDirection, 1.0f), -1.0f);
            }
            changingView.performRemoveAnimation(ANIMATION_DURATION_APPEAR_DISAPPEAR, translationDirection, new Runnable() {

                @Override
                public void run() {
                    // remove the temporary overlay
                    removeFromOverlay(changingView);
                }
            });
        } 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 was fully swiped out. So let's remove it
            mHostLayout.getOverlay().remove(changingView);
            if (Math.abs(changingView.getTranslation()) == changingView.getWidth() && changingView.getTransientContainer() != null) {
                changingView.getTransientContainer().removeTransientView(changingView);
            }
        } else if (event.animationType == NotificationStackScrollLayout.AnimationEvent.ANIMATION_TYPE_GROUP_EXPANSION_CHANGED) {
            ExpandableNotificationRow row = (ExpandableNotificationRow) event.changingView;
            row.prepareExpansionChanged(finalState);
        } else if (event.animationType == NotificationStackScrollLayout.AnimationEvent.ANIMATION_TYPE_HEADS_UP_APPEAR) {
            // This item is added, initialize it's properties.
            StackViewState viewState = finalState.getViewStateForView(changingView);
            mTmpState.copyFrom(viewState);
            if (event.headsUpFromBottom) {
                mTmpState.yTranslation = mHeadsUpAppearHeightBottom;
            } else {
                mTmpState.yTranslation = -mTmpState.height;
            }
            mHeadsUpAppearChildren.add(changingView);
            finalState.applyState(changingView, mTmpState);
        } else if (event.animationType == NotificationStackScrollLayout.AnimationEvent.ANIMATION_TYPE_HEADS_UP_DISAPPEAR || event.animationType == NotificationStackScrollLayout.AnimationEvent.ANIMATION_TYPE_HEADS_UP_DISAPPEAR_CLICK) {
            mHeadsUpDisappearChildren.add(changingView);
            if (changingView.getParent() == null) {
                // This notification was actually removed, so we need to add it to the overlay
                mHostLayout.getOverlay().add(changingView);
                mTmpState.initFrom(changingView);
                mTmpState.yTranslation = -changingView.getActualHeight();
                // We temporarily enable Y animations, the real filter will be combined
                // afterwards anyway
                mAnimationFilter.animateY = true;
                startViewAnimations(changingView, mTmpState, event.animationType == NotificationStackScrollLayout.AnimationEvent.ANIMATION_TYPE_HEADS_UP_DISAPPEAR_CLICK ? ANIMATION_DELAY_HEADS_UP : 0, ANIMATION_DURATION_HEADS_UP_DISAPPEAR);
                mChildrenToClearFromOverlay.add(changingView);
            }
        }
        mNewEvents.add(event);
    }
}
Also used : ExpandableView(com.android.systemui.statusbar.ExpandableView) ExpandableNotificationRow(com.android.systemui.statusbar.ExpandableNotificationRow)

Example 13 with ExpandableNotificationRow

use of com.android.systemui.statusbar.ExpandableNotificationRow in project platform_frameworks_base by android.

the class StackStateAnimator method startHeightAnimation.

private void startHeightAnimation(final ExpandableView child, StackViewState viewState, long duration, long delay) {
    Integer previousStartValue = getChildTag(child, TAG_START_HEIGHT);
    Integer previousEndValue = getChildTag(child, TAG_END_HEIGHT);
    int newEndValue = viewState.height;
    if (previousEndValue != null && previousEndValue == newEndValue) {
        return;
    }
    ValueAnimator previousAnimator = getChildTag(child, TAG_ANIMATOR_HEIGHT);
    if (!mAnimationFilter.animateHeight) {
        // just a local update was performed
        if (previousAnimator != null) {
            // we need to increase all animation keyframes of the previous animator by the
            // relative change to the end value
            PropertyValuesHolder[] values = previousAnimator.getValues();
            int relativeDiff = newEndValue - previousEndValue;
            int newStartValue = previousStartValue + relativeDiff;
            values[0].setIntValues(newStartValue, newEndValue);
            child.setTag(TAG_START_HEIGHT, newStartValue);
            child.setTag(TAG_END_HEIGHT, newEndValue);
            previousAnimator.setCurrentPlayTime(previousAnimator.getCurrentPlayTime());
            return;
        } else {
            // no new animation needed, let's just apply the value
            child.setActualHeight(newEndValue, false);
            return;
        }
    }
    ValueAnimator animator = ValueAnimator.ofInt(child.getActualHeight(), newEndValue);
    animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {

        @Override
        public void onAnimationUpdate(ValueAnimator animation) {
            child.setActualHeight((int) animation.getAnimatedValue(), false);
        }
    });
    animator.setInterpolator(Interpolators.FAST_OUT_SLOW_IN);
    long newDuration = cancelAnimatorAndGetNewDuration(duration, previousAnimator);
    animator.setDuration(newDuration);
    if (delay > 0 && (previousAnimator == null || previousAnimator.getAnimatedFraction() == 0)) {
        animator.setStartDelay(delay);
    }
    animator.addListener(getGlobalAnimationFinishedListener());
    // remove the tag when the animation is finished
    animator.addListener(new AnimatorListenerAdapter() {

        boolean mWasCancelled;

        @Override
        public void onAnimationEnd(Animator animation) {
            child.setTag(TAG_ANIMATOR_HEIGHT, null);
            child.setTag(TAG_START_HEIGHT, null);
            child.setTag(TAG_END_HEIGHT, null);
            child.setActualHeightAnimating(false);
            if (!mWasCancelled && child instanceof ExpandableNotificationRow) {
                ((ExpandableNotificationRow) child).setGroupExpansionChanging(false);
            }
        }

        @Override
        public void onAnimationStart(Animator animation) {
            mWasCancelled = false;
        }

        @Override
        public void onAnimationCancel(Animator animation) {
            mWasCancelled = true;
        }
    });
    startAnimator(animator);
    child.setTag(TAG_ANIMATOR_HEIGHT, animator);
    child.setTag(TAG_START_HEIGHT, child.getActualHeight());
    child.setTag(TAG_END_HEIGHT, newEndValue);
    child.setActualHeightAnimating(true);
}
Also used : ObjectAnimator(android.animation.ObjectAnimator) Animator(android.animation.Animator) ValueAnimator(android.animation.ValueAnimator) AnimatorListenerAdapter(android.animation.AnimatorListenerAdapter) PropertyValuesHolder(android.animation.PropertyValuesHolder) ValueAnimator(android.animation.ValueAnimator) ExpandableNotificationRow(com.android.systemui.statusbar.ExpandableNotificationRow)

Example 14 with ExpandableNotificationRow

use of com.android.systemui.statusbar.ExpandableNotificationRow in project platform_frameworks_base by android.

the class NotificationChildrenContainer method getState.

/**
     * Update the state of all its children based on a linear layout algorithm.
     *
     * @param resultState the state to update
     * @param parentState the state of the parent
     */
public void getState(StackScrollState resultState, StackViewState parentState) {
    int childCount = mChildren.size();
    int yPosition = mNotificationHeaderMargin;
    boolean firstChild = true;
    int maxAllowedVisibleChildren = getMaxAllowedVisibleChildren();
    int lastVisibleIndex = maxAllowedVisibleChildren - 1;
    int firstOverflowIndex = lastVisibleIndex + 1;
    float expandFactor = 0;
    if (mUserLocked) {
        expandFactor = getGroupExpandFraction();
        firstOverflowIndex = getMaxAllowedVisibleChildren(true);
    }
    boolean childrenExpanded = !mNotificationParent.isGroupExpansionChanging() && mChildrenExpanded;
    int parentHeight = parentState.height;
    for (int i = 0; i < childCount; i++) {
        ExpandableNotificationRow child = mChildren.get(i);
        if (!firstChild) {
            if (mUserLocked) {
                yPosition += NotificationUtils.interpolate(mChildPadding, mDividerHeight, expandFactor);
            } else {
                yPosition += mChildrenExpanded ? mDividerHeight : mChildPadding;
            }
        } else {
            if (mUserLocked) {
                yPosition += NotificationUtils.interpolate(0, mNotificatonTopPadding + mDividerHeight, expandFactor);
            } else {
                yPosition += mChildrenExpanded ? mNotificatonTopPadding + mDividerHeight : 0;
            }
            firstChild = false;
        }
        StackViewState childState = resultState.getViewStateForView(child);
        int intrinsicHeight = child.getIntrinsicHeight();
        if (childrenExpanded) {
            // adjusts its height to move into it. Children after it are hidden.
            if (updateChildStateForExpandedGroup(child, parentHeight, childState, yPosition)) {
                // Clipping might be deactivated if the view is transforming, however, clipping
                // the child into the bottom stack should take precedent over this.
                childState.isBottomClipped = true;
            }
        } else {
            childState.hidden = false;
            childState.height = intrinsicHeight;
            childState.isBottomClipped = false;
        }
        childState.yTranslation = yPosition;
        // When the group is expanded, the children cast the shadows rather than the parent
        // so use the parent's elevation here.
        childState.zTranslation = childrenExpanded ? mNotificationParent.getTranslationZ() : 0;
        childState.dimmed = parentState.dimmed;
        childState.dark = parentState.dark;
        childState.hideSensitive = parentState.hideSensitive;
        childState.belowSpeedBump = parentState.belowSpeedBump;
        childState.clipTopAmount = 0;
        childState.alpha = 0;
        if (i < firstOverflowIndex) {
            childState.alpha = 1;
        } else if (expandFactor == 1.0f && i <= lastVisibleIndex) {
            childState.alpha = (mActualHeight - childState.yTranslation) / childState.height;
            childState.alpha = Math.max(0.0f, Math.min(1.0f, childState.alpha));
        }
        childState.location = parentState.location;
        yPosition += intrinsicHeight;
    }
    if (mOverflowNumber != null) {
        ExpandableNotificationRow overflowView = mChildren.get(Math.min(getMaxAllowedVisibleChildren(true), childCount) - 1);
        mGroupOverFlowState.copyFrom(resultState.getViewStateForView(overflowView));
        if (!mChildrenExpanded) {
            if (mUserLocked) {
                HybridNotificationView singleLineView = overflowView.getSingleLineView();
                View mirrorView = singleLineView.getTextView();
                if (mirrorView.getVisibility() == GONE) {
                    mirrorView = singleLineView.getTitleView();
                }
                if (mirrorView.getVisibility() == GONE) {
                    mirrorView = singleLineView;
                }
                mGroupOverFlowState.yTranslation += NotificationUtils.getRelativeYOffset(mirrorView, overflowView);
                mGroupOverFlowState.alpha = mirrorView.getAlpha();
            }
        } else {
            mGroupOverFlowState.yTranslation += mNotificationHeaderMargin;
            mGroupOverFlowState.alpha = 0.0f;
        }
    }
    if (mNotificationHeader != null) {
        if (mHeaderViewState == null) {
            mHeaderViewState = new ViewState();
        }
        mHeaderViewState.initFrom(mNotificationHeader);
        mHeaderViewState.zTranslation = childrenExpanded ? mNotificationParent.getTranslationZ() : 0;
    }
}
Also used : HybridNotificationView(com.android.systemui.statusbar.notification.HybridNotificationView) TextView(android.widget.TextView) NotificationPanelView(com.android.systemui.statusbar.phone.NotificationPanelView) View(android.view.View) HybridNotificationView(com.android.systemui.statusbar.notification.HybridNotificationView) NotificationHeaderView(android.view.NotificationHeaderView) ExpandableNotificationRow(com.android.systemui.statusbar.ExpandableNotificationRow)

Example 15 with ExpandableNotificationRow

use of com.android.systemui.statusbar.ExpandableNotificationRow in project platform_frameworks_base by android.

the class NotificationChildrenContainer method setActualHeight.

public void setActualHeight(int actualHeight) {
    if (!mUserLocked) {
        return;
    }
    mActualHeight = actualHeight;
    float fraction = getGroupExpandFraction();
    int maxAllowedVisibleChildren = getMaxAllowedVisibleChildren(true);
    int childCount = mChildren.size();
    for (int i = 0; i < childCount; i++) {
        ExpandableNotificationRow child = mChildren.get(i);
        float childHeight = child.isExpanded(true) ? child.getMaxExpandHeight() : child.getShowingLayout().getMinHeight(true);
        if (i < maxAllowedVisibleChildren) {
            float singleLineHeight = child.getShowingLayout().getMinHeight(false);
            child.setActualHeight((int) NotificationUtils.interpolate(singleLineHeight, childHeight, fraction), false);
        } else {
            child.setActualHeight((int) childHeight, false);
        }
    }
}
Also used : ExpandableNotificationRow(com.android.systemui.statusbar.ExpandableNotificationRow)

Aggregations

ExpandableNotificationRow (com.android.systemui.statusbar.ExpandableNotificationRow)290 View (android.view.View)75 ExpandableView (com.android.systemui.statusbar.ExpandableView)75 TextView (android.widget.TextView)55 ActivatableNotificationView (com.android.systemui.statusbar.ActivatableNotificationView)45 DismissView (com.android.systemui.statusbar.DismissView)45 EmptyShadeView (com.android.systemui.statusbar.EmptyShadeView)45 Paint (android.graphics.Paint)40 ImageView (android.widget.ImageView)35 Point (android.graphics.Point)30 BatteryMeterView (com.android.systemui.BatteryMeterView)30 BackDropView (com.android.systemui.statusbar.BackDropView)30 ScrimView (com.android.systemui.statusbar.ScrimView)30 SignalClusterView (com.android.systemui.statusbar.SignalClusterView)30 NotificationHeaderView (android.view.NotificationHeaderView)25 BatteryLevelTextView (com.android.systemui.BatteryLevelTextView)24 KeyButtonView (com.android.systemui.statusbar.policy.KeyButtonView)24 StackScrollerDecorView (com.android.systemui.statusbar.StackScrollerDecorView)20 FakeShadowView (com.android.systemui.statusbar.notification.FakeShadowView)20 HybridNotificationView (com.android.systemui.statusbar.notification.HybridNotificationView)20