Refinements for app transitions
- Use refined interpolator for most of the transitions which respond
to touch faster than a normal fast_out_slow_in interpolator.
- Tune clip reveal animation: Get rid of horizontal movement, only do
slight vertical movement, and make horizontal reveal animation faster
so there is a more staggered animation to resemble an opening paper
Change-Id: Id94328906f9b194fb97d702e9b102c7aeef96bb8
diff --git a/services/core/java/com/android/server/wm/AppTransition.java b/services/core/java/com/android/server/wm/AppTransition.java
index 60bbc48..cd4555d5 100644
--- a/services/core/java/com/android/server/wm/AppTransition.java
+++ b/services/core/java/com/android/server/wm/AppTransition.java
@@ -34,11 +34,11 @@
import android.view.animation.ClipRectLRAnimation;
import android.view.animation.ClipRectTBAnimation;
import android.view.animation.Interpolator;
-import android.view.animation.LinearInterpolator;
+import android.view.animation.PathInterpolator;
import android.view.animation.ScaleAnimation;
import android.view.animation.TranslateAnimation;
-import android.view.animation.TranslateXAnimation;
import android.view.animation.TranslateYAnimation;
+
import com.android.internal.util.DumpUtils.Dump;
import com.android.server.AttributeCache;
import com.android.server.wm.WindowManagerService.H;
@@ -47,28 +47,28 @@
import java.util.ArrayList;
import static android.view.WindowManagerInternal.AppTransitionListener;
-import static com.android.internal.R.styleable.WindowAnimation_activityOpenEnterAnimation;
-import static com.android.internal.R.styleable.WindowAnimation_activityOpenExitAnimation;
import static com.android.internal.R.styleable.WindowAnimation_activityCloseEnterAnimation;
import static com.android.internal.R.styleable.WindowAnimation_activityCloseExitAnimation;
-import static com.android.internal.R.styleable.WindowAnimation_taskOpenEnterAnimation;
-import static com.android.internal.R.styleable.WindowAnimation_taskOpenExitAnimation;
-import static com.android.internal.R.styleable.WindowAnimation_launchTaskBehindTargetAnimation;
+import static com.android.internal.R.styleable.WindowAnimation_activityOpenEnterAnimation;
+import static com.android.internal.R.styleable.WindowAnimation_activityOpenExitAnimation;
import static com.android.internal.R.styleable.WindowAnimation_launchTaskBehindSourceAnimation;
+import static com.android.internal.R.styleable.WindowAnimation_launchTaskBehindTargetAnimation;
import static com.android.internal.R.styleable.WindowAnimation_taskCloseEnterAnimation;
import static com.android.internal.R.styleable.WindowAnimation_taskCloseExitAnimation;
-import static com.android.internal.R.styleable.WindowAnimation_taskToFrontEnterAnimation;
-import static com.android.internal.R.styleable.WindowAnimation_taskToFrontExitAnimation;
+import static com.android.internal.R.styleable.WindowAnimation_taskOpenEnterAnimation;
+import static com.android.internal.R.styleable.WindowAnimation_taskOpenExitAnimation;
import static com.android.internal.R.styleable.WindowAnimation_taskToBackEnterAnimation;
import static com.android.internal.R.styleable.WindowAnimation_taskToBackExitAnimation;
-import static com.android.internal.R.styleable.WindowAnimation_wallpaperOpenEnterAnimation;
-import static com.android.internal.R.styleable.WindowAnimation_wallpaperOpenExitAnimation;
+import static com.android.internal.R.styleable.WindowAnimation_taskToFrontEnterAnimation;
+import static com.android.internal.R.styleable.WindowAnimation_taskToFrontExitAnimation;
import static com.android.internal.R.styleable.WindowAnimation_wallpaperCloseEnterAnimation;
import static com.android.internal.R.styleable.WindowAnimation_wallpaperCloseExitAnimation;
-import static com.android.internal.R.styleable.WindowAnimation_wallpaperIntraOpenEnterAnimation;
-import static com.android.internal.R.styleable.WindowAnimation_wallpaperIntraOpenExitAnimation;
import static com.android.internal.R.styleable.WindowAnimation_wallpaperIntraCloseEnterAnimation;
import static com.android.internal.R.styleable.WindowAnimation_wallpaperIntraCloseExitAnimation;
+import static com.android.internal.R.styleable.WindowAnimation_wallpaperIntraOpenEnterAnimation;
+import static com.android.internal.R.styleable.WindowAnimation_wallpaperIntraOpenExitAnimation;
+import static com.android.internal.R.styleable.WindowAnimation_wallpaperOpenEnterAnimation;
+import static com.android.internal.R.styleable.WindowAnimation_wallpaperOpenExitAnimation;
// State management of app transitions. When we are preparing for a
// transition, mNextAppTransition will be the kind of transition to
@@ -80,7 +80,7 @@
private static final boolean DEBUG_APP_TRANSITIONS =
WindowManagerService.DEBUG_APP_TRANSITIONS;
private static final boolean DEBUG_ANIM = WindowManagerService.DEBUG_ANIM;
-
+ private static final int CLIP_REVEAL_TRANSLATION_Y_DP = 8;
/** Not set up for a transition. */
public static final int TRANSIT_UNSET = -1;
@@ -121,13 +121,13 @@
public static final int TRANSIT_TASK_IN_PLACE = 17;
/** Fraction of animation at which the recents thumbnail stays completely transparent */
- private static final float RECENTS_THUMBNAIL_FADEIN_FRACTION = 0.7f;
+ private static final float RECENTS_THUMBNAIL_FADEIN_FRACTION = 0.5f;
/** Fraction of animation at which the recents thumbnail becomes completely transparent */
- private static final float RECENTS_THUMBNAIL_FADEOUT_FRACTION = 0.3f;
+ private static final float RECENTS_THUMBNAIL_FADEOUT_FRACTION = 0.5f;
- private static final int DEFAULT_APP_TRANSITION_DURATION = 250;
- private static final int THUMBNAIL_APP_TRANSITION_DURATION = 325;
- private static final int THUMBNAIL_APP_TRANSITION_ALPHA_DURATION = 325;
+ private static final int DEFAULT_APP_TRANSITION_DURATION = 336;
+ private static final int THUMBNAIL_APP_TRANSITION_DURATION = 336;
+ private static final int THUMBNAIL_APP_TRANSITION_ALPHA_DURATION = 336;
private final Context mContext;
private final Handler mH;
@@ -179,8 +179,14 @@
private final Interpolator mThumbnailFadeInInterpolator;
private final Interpolator mThumbnailFadeOutInterpolator;
private final Interpolator mLinearOutSlowInInterpolator;
- private final Interpolator mFastOutSlowInInterpolator;
- private final LinearInterpolator mLinearInterpolator;
+ private final Interpolator mFastOutLinearInInterpolator;
+ private final Interpolator mClipHorizontalInterpolator = new PathInterpolator(0, 0, 0.4f, 1f);
+
+ /** Interpolator to be used for animations that respond directly to a touch */
+ private final Interpolator mTouchResponseInterpolator =
+ new PathInterpolator(0.3f, 0f, 0.1f, 1f);
+
+ private final int mClipRevealTranslationY;
private int mCurrentUserId = 0;
@@ -191,9 +197,8 @@
mH = h;
mLinearOutSlowInInterpolator = AnimationUtils.loadInterpolator(context,
com.android.internal.R.interpolator.linear_out_slow_in);
- mFastOutSlowInInterpolator = AnimationUtils.loadInterpolator(context,
- com.android.internal.R.interpolator.fast_out_slow_in);
- mLinearInterpolator = new LinearInterpolator();
+ mFastOutLinearInInterpolator = AnimationUtils.loadInterpolator(context,
+ com.android.internal.R.interpolator.fast_out_linear_in);
mConfigShortAnimTime = context.getResources().getInteger(
com.android.internal.R.integer.config_shortAnimTime);
mDecelerateInterpolator = AnimationUtils.loadInterpolator(context,
@@ -205,8 +210,9 @@
if (input < RECENTS_THUMBNAIL_FADEIN_FRACTION) {
return 0f;
}
- return (input - RECENTS_THUMBNAIL_FADEIN_FRACTION) /
+ float t = (input - RECENTS_THUMBNAIL_FADEIN_FRACTION) /
(1f - RECENTS_THUMBNAIL_FADEIN_FRACTION);
+ return mFastOutLinearInInterpolator.getInterpolation(t);
}
};
mThumbnailFadeOutInterpolator = new Interpolator() {
@@ -214,11 +220,14 @@
public float getInterpolation(float input) {
// Linear response for first fraction, then complete after that.
if (input < RECENTS_THUMBNAIL_FADEOUT_FRACTION) {
- return input / RECENTS_THUMBNAIL_FADEOUT_FRACTION;
+ float t = input / RECENTS_THUMBNAIL_FADEOUT_FRACTION;
+ return mLinearOutSlowInInterpolator.getInterpolation(t);
}
return 1f;
}
};
+ mClipRevealTranslationY = (int) (CLIP_REVEAL_TRANSLATION_Y_DP
+ * mContext.getResources().getDisplayMetrics().density);
}
boolean isTransitionSet() {
@@ -507,47 +516,47 @@
if (enter) {
// Reveal will expand and move faster in horizontal direction
- // Start from upper left of start and move to final position
final int appWidth = appFrame.width();
final int appHeight = appFrame.height();
- // Start from size of launch icon, expand to full width/height
+ float t = 0f;
+ if (appHeight > 0) {
+ t = (float) mNextAppTransitionStartY / appHeight;
+ }
+ int translationY = mClipRevealTranslationY
+ + (int)(appHeight / 7f * t);
+
+ int centerX = mNextAppTransitionStartX + mNextAppTransitionStartWidth / 2;
+ int centerY = mNextAppTransitionStartY + mNextAppTransitionStartHeight / 2;
+
+ // Clip third of the from size of launch icon, expand to full width/height
Animation clipAnimLR = new ClipRectLRAnimation(
- (appWidth - mNextAppTransitionStartWidth) / 2,
- (appWidth + mNextAppTransitionStartWidth) / 2, 0, appWidth);
- clipAnimLR.setInterpolator(mLinearOutSlowInInterpolator);
- clipAnimLR.setDuration(DEFAULT_APP_TRANSITION_DURATION);
+ centerX - mNextAppTransitionStartWidth / 3,
+ centerX + mNextAppTransitionStartWidth / 3,
+ 0, appWidth);
+ clipAnimLR.setInterpolator(mClipHorizontalInterpolator);
+ clipAnimLR.setDuration((long) (DEFAULT_APP_TRANSITION_DURATION / 2.5f));
Animation clipAnimTB = new ClipRectTBAnimation(
- (appHeight - mNextAppTransitionStartHeight) / 2,
- (appHeight + mNextAppTransitionStartHeight) / 2, 0, appHeight);
- clipAnimTB.setInterpolator(mFastOutSlowInInterpolator);
+ centerY - mNextAppTransitionStartHeight / 3 - translationY,
+ centerY + mNextAppTransitionStartHeight / 3 - translationY,
+ 0, appHeight);
+ clipAnimTB.setInterpolator(mTouchResponseInterpolator);
clipAnimTB.setDuration(DEFAULT_APP_TRANSITION_DURATION);
- // Start from middle of launch icon area, move to 0, 0
- int startMiddleX = mNextAppTransitionStartX +
- (mNextAppTransitionStartWidth - appWidth) / 2 - appFrame.left;
- int startMiddleY = mNextAppTransitionStartY +
- (mNextAppTransitionStartHeight - appHeight) / 2 - appFrame.top;
-
- TranslateXAnimation translateX = new TranslateXAnimation(
- Animation.ABSOLUTE, startMiddleX, Animation.ABSOLUTE, 0);
- translateX.setInterpolator(mLinearOutSlowInInterpolator);
- translateX.setDuration(DEFAULT_APP_TRANSITION_DURATION);
TranslateYAnimation translateY = new TranslateYAnimation(
- Animation.ABSOLUTE, startMiddleY, Animation.ABSOLUTE, 0);
- translateY.setInterpolator(mFastOutSlowInInterpolator);
+ Animation.ABSOLUTE, translationY, Animation.ABSOLUTE, 0);
+ translateY.setInterpolator(mLinearOutSlowInInterpolator);
translateY.setDuration(DEFAULT_APP_TRANSITION_DURATION);
// Quick fade-in from icon to app window
- final int alphaDuration = 100;
- AlphaAnimation alpha = new AlphaAnimation(0.1f, 1);
+ final int alphaDuration = DEFAULT_APP_TRANSITION_DURATION / 4;
+ AlphaAnimation alpha = new AlphaAnimation(0.5f, 1);
alpha.setDuration(alphaDuration);
- alpha.setInterpolator(mLinearInterpolator);
+ alpha.setInterpolator(mLinearOutSlowInInterpolator);
AnimationSet set = new AnimationSet(false);
set.addAnimation(clipAnimLR);
set.addAnimation(clipAnimTB);
- set.addAnimation(translateX);
set.addAnimation(translateY);
set.addAnimation(alpha);
set.initialize(appWidth, appHeight, appWidth, appHeight);
@@ -657,14 +666,14 @@
Animation scale = new ScaleAnimation(1f, scaleW, 1f, scaleW,
mNextAppTransitionStartX + (thumbWidth / 2f),
mNextAppTransitionStartY + (thumbHeight / 2f));
- scale.setInterpolator(mFastOutSlowInInterpolator);
+ scale.setInterpolator(mTouchResponseInterpolator);
scale.setDuration(THUMBNAIL_APP_TRANSITION_DURATION);
Animation alpha = new AlphaAnimation(1, 0);
alpha.setInterpolator(mThumbnailFadeOutInterpolator);
alpha.setDuration(THUMBNAIL_APP_TRANSITION_ALPHA_DURATION);
Animation translate = new TranslateAnimation(0, 0, 0, -unscaledStartY +
mNextAppTransitionInsets.top);
- translate.setInterpolator(mFastOutSlowInInterpolator);
+ translate.setInterpolator(mTouchResponseInterpolator);
translate.setDuration(THUMBNAIL_APP_TRANSITION_DURATION);
// This AnimationSet uses the Interpolators assigned above.
@@ -678,14 +687,14 @@
Animation scale = new ScaleAnimation(scaleW, 1f, scaleW, 1f,
mNextAppTransitionStartX + (thumbWidth / 2f),
mNextAppTransitionStartY + (thumbHeight / 2f));
- scale.setInterpolator(mFastOutSlowInInterpolator);
+ scale.setInterpolator(mTouchResponseInterpolator);
scale.setDuration(THUMBNAIL_APP_TRANSITION_DURATION);
Animation alpha = new AlphaAnimation(0f, 1f);
alpha.setInterpolator(mThumbnailFadeInInterpolator);
alpha.setDuration(THUMBNAIL_APP_TRANSITION_ALPHA_DURATION);
Animation translate = new TranslateAnimation(0, 0, -unscaledStartY +
mNextAppTransitionInsets.top, 0);
- translate.setInterpolator(mFastOutSlowInInterpolator);
+ translate.setInterpolator(mTouchResponseInterpolator);
translate.setDuration(THUMBNAIL_APP_TRANSITION_DURATION);
// This AnimationSet uses the Interpolators assigned above.
@@ -697,7 +706,7 @@
}
return prepareThumbnailAnimationWithDuration(a, appWidth, appHeight, 0,
- mFastOutSlowInInterpolator);
+ mTouchResponseInterpolator);
}
/**
@@ -833,7 +842,7 @@
int duration = Math.max(THUMBNAIL_APP_TRANSITION_ALPHA_DURATION,
THUMBNAIL_APP_TRANSITION_DURATION);
return prepareThumbnailAnimationWithDuration(a, appWidth, appHeight, duration,
- mFastOutSlowInInterpolator);
+ mTouchResponseInterpolator);
}
/**