OSDN Git Service

Fixed more heads up bugs
[android-x86/frameworks-base.git] / packages / SystemUI / src / com / android / systemui / statusbar / stack / StackStateAnimator.java
index b249fbf..4a705b5 100644 (file)
@@ -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())) {
@@ -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;
+    }
 }