summaryrefslogtreecommitdiffstats
path: root/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackStateAnimator.java
diff options
context:
space:
mode:
Diffstat (limited to 'packages/SystemUI/src/com/android/systemui/statusbar/stack/StackStateAnimator.java')
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/stack/StackStateAnimator.java94
1 files changed, 88 insertions, 6 deletions
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackStateAnimator.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackStateAnimator.java
index b249fbf..f5d94c8 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackStateAnimator.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackStateAnimator.java
@@ -21,9 +21,11 @@ import android.animation.AnimatorListenerAdapter;
import android.animation.ObjectAnimator;
import android.animation.PropertyValuesHolder;
import android.animation.ValueAnimator;
+import android.graphics.Path;
import android.view.View;
import android.view.animation.AnimationUtils;
import android.view.animation.Interpolator;
+import android.view.animation.PathInterpolator;
import com.android.systemui.R;
import com.android.systemui.statusbar.ExpandableNotificationRow;
@@ -32,7 +34,6 @@ import com.android.systemui.statusbar.SpeedBumpView;
import java.util.ArrayList;
import java.util.HashSet;
-import java.util.Set;
import java.util.Stack;
/**
@@ -45,6 +46,8 @@ public class StackStateAnimator {
public static final int ANIMATION_DURATION_APPEAR_DISAPPEAR = 464;
public static final int ANIMATION_DURATION_EXPAND_CLICKED = 360;
public static final int ANIMATION_DURATION_DIMMED_ACTIVATED = 220;
+ public static final int ANIMATION_DURATION_HEADS_UP_APPEAR = 650;
+ public static final int ANIMATION_DURATION_HEADS_UP_DISAPPEAR = 230;
public static final int ANIMATION_DELAY_PER_ELEMENT_INTERRUPTING = 80;
public static final int ANIMATION_DELAY_PER_ELEMENT_EXPAND_CHILDREN = 54;
public static final int ANIMATION_DELAY_PER_ELEMENT_MANUAL = 32;
@@ -73,12 +76,15 @@ public class StackStateAnimator {
private static final int TAG_START_TOP_INSET = R.id.top_inset_animator_start_value_tag;
private final Interpolator mFastOutSlowInInterpolator;
+ private final Interpolator mHeadsUpAppearInterpolator;
private final int mGoToFullShadeAppearingTranslation;
public NotificationStackScrollLayout mHostLayout;
private ArrayList<NotificationStackScrollLayout.AnimationEvent> mNewEvents =
new ArrayList<>();
private ArrayList<View> mNewAddChildren = new ArrayList<>();
- private Set<Animator> mAnimatorSet = new HashSet<>();
+ private HashSet<View> mHeadsUpAppearChildren = new HashSet<>();
+ private HashSet<View> mHeadsUpDisappearChildren = new HashSet<>();
+ private HashSet<Animator> mAnimatorSet = new HashSet<>();
private Stack<AnimatorListenerAdapter> mAnimationListenerPool = new Stack<>();
private AnimationFilter mAnimationFilter = new AnimationFilter();
private long mCurrentLength;
@@ -86,10 +92,12 @@ public class StackStateAnimator {
/** The current index for the last child which was not added in this event set. */
private int mCurrentLastNotAddedIndex;
-
private ValueAnimator mTopOverScrollAnimator;
private ValueAnimator mBottomOverScrollAnimator;
private ExpandableNotificationRow mChildExpandingView;
+ private StackViewState mTmpState = new StackViewState();
+ private int mHeadsUpAppearHeightBottom;
+ private boolean mShadeExpanded;
public StackStateAnimator(NotificationStackScrollLayout hostLayout) {
mHostLayout = hostLayout;
@@ -98,6 +106,25 @@ public class StackStateAnimator {
mGoToFullShadeAppearingTranslation =
hostLayout.getContext().getResources().getDimensionPixelSize(
R.dimen.go_to_full_shade_appearing_translation);
+ Path path = new Path();
+ path.moveTo(0, 0);
+ float x1 = 250f;
+ float x2 = 150f;
+ float x3 = 100f;
+ float y1 = 90f;
+ float y2 = 78f;
+ float y3 = 80f;
+ float xTot = (x1 + x2 + x3);
+ path.cubicTo(x1 * 0.9f / xTot, 0f,
+ x1 * 0.8f / xTot, y1 / y3,
+ x1 / xTot , y1 / y3);
+ path.cubicTo((x1 + x2 * 0.4f) / xTot, y1 / y3,
+ (x1 + x2 * 0.2f) / xTot, y2 / y3,
+ (x1 + x2) / xTot, y2 / y3);
+ path.cubicTo((x1 + x2 + x3 * 0.4f) / xTot, y2 / y3,
+ (x1 + x2 + x3 * 0.2f) / xTot, 1f,
+ 1f, 1f);
+ mHeadsUpAppearInterpolator = new PathInterpolator(path);
}
public boolean isRunning() {
@@ -119,7 +146,8 @@ public class StackStateAnimator {
final ExpandableView child = (ExpandableView) mHostLayout.getChildAt(i);
StackViewState viewState = finalState.getViewStateForView(child);
- if (viewState == null || child.getVisibility() == View.GONE) {
+ if (viewState == null || child.getVisibility() == View.GONE
+ || applyWithoutAnimation(child, viewState, finalState)) {
continue;
}
@@ -130,11 +158,39 @@ public class StackStateAnimator {
// no child has preformed any animation, lets finish
onAnimationFinished();
}
+ mHeadsUpAppearChildren.clear();
+ mHeadsUpDisappearChildren.clear();
mNewEvents.clear();
mNewAddChildren.clear();
mChildExpandingView = null;
}
+ /**
+ * Determines if a view should not perform an animation and applies it directly.
+ *
+ * @return true if no animation should be performed
+ */
+ private boolean applyWithoutAnimation(ExpandableView child, StackViewState viewState,
+ StackScrollState finalState) {
+ if (mShadeExpanded) {
+ return false;
+ }
+ if (getChildTag(child, TAG_ANIMATOR_TRANSLATION_Y) != null) {
+ // A Y translation animation is running
+ return false;
+ }
+ if (mHeadsUpDisappearChildren.contains(child) || mHeadsUpAppearChildren.contains(child)) {
+ // This is a heads up animation
+ return false;
+ }
+ if (mHostLayout.isPinnedHeadsUp(child)) {
+ // This is another headsUp which might move. Let's animate!
+ return false;
+ }
+ finalState.applyState(child, viewState);
+ return true;
+ }
+
private int findLastNotAddedIndex(StackScrollState finalState) {
int childCount = mHostLayout.getChildCount();
for (int i = childCount - 1; i >= 0; i--) {
@@ -616,7 +672,9 @@ public class StackStateAnimator {
ObjectAnimator animator = ObjectAnimator.ofFloat(child, View.TRANSLATION_Y,
child.getTranslationY(), newEndValue);
- animator.setInterpolator(mFastOutSlowInInterpolator);
+ Interpolator interpolator = mHeadsUpAppearChildren.contains(child) ?
+ mHeadsUpAppearInterpolator :mFastOutSlowInInterpolator;
+ animator.setInterpolator(interpolator);
long newDuration = cancelAnimatorAndGetNewDuration(duration, previousAnimator);
animator.setDuration(newDuration);
if (delay > 0 && (previousAnimator == null || !previousAnimator.isRunning())) {
@@ -731,7 +789,7 @@ public class StackStateAnimator {
};
}
- private static <T> T getChildTag(View child, int tag) {
+ public static <T> T getChildTag(View child, int tag) {
return (T) child.getTag(tag);
}
@@ -828,6 +886,22 @@ public class StackStateAnimator {
ExpandableNotificationRow row = (ExpandableNotificationRow) event.changingView;
row.prepareExpansionChanged(finalState);
mChildExpandingView = row;
+ } 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) {
+ // This item is added, initialize it's properties.
+ mHeadsUpDisappearChildren.add(changingView);
}
mNewEvents.add(event);
}
@@ -893,4 +967,12 @@ public class StackStateAnimator {
return getChildTag(view, TAG_END_HEIGHT);
}
}
+
+ public void setHeadsUpAppearHeightBottom(int headsUpAppearHeightBottom) {
+ mHeadsUpAppearHeightBottom = headsUpAppearHeightBottom;
+ }
+
+ public void setShadeExpanded(boolean shadeExpanded) {
+ mShadeExpanded = shadeExpanded;
+ }
}