From 191e9d1b297f3a5dd2953f00c9cf9eac364fcf69 Mon Sep 17 00:00:00 2001 From: Hyunyoung Song Date: Wed, 3 Aug 2016 15:14:43 -0700 Subject: Change interpolation logic to all apps transitioning on fling b/30486958 Cleaning up/refactoring this CL will be done in polish branch. Change-Id: Ib51633a1e1cb79f58b505f835053ef238ae1bdec --- .../LauncherStateTransitionAnimation.java | 76 ++++++++++++---------- .../allapps/AllAppsTransitionController.java | 60 +++++++++++++---- 2 files changed, 87 insertions(+), 49 deletions(-) (limited to 'src/com/android/launcher3') diff --git a/src/com/android/launcher3/LauncherStateTransitionAnimation.java b/src/com/android/launcher3/LauncherStateTransitionAnimation.java index b6e2e4c2e..2b1ebdebe 100644 --- a/src/com/android/launcher3/LauncherStateTransitionAnimation.java +++ b/src/com/android/launcher3/LauncherStateTransitionAnimation.java @@ -174,7 +174,7 @@ public class LauncherStateTransitionAnimation { animType = PULLUP; } // Only animate the search bar if animating from spring loaded mode back to all apps - mCurrentAnimation = startAnimationToOverlay(fromWorkspaceState, + startAnimationToOverlay(fromWorkspaceState, Workspace.State.NORMAL_HIDDEN, buttonView, toView, animated, animType, cb); } @@ -185,7 +185,7 @@ public class LauncherStateTransitionAnimation { final boolean animated) { final WidgetsContainerView toView = mLauncher.getWidgetsView(); final View buttonView = mLauncher.getWidgetsButton(); - mCurrentAnimation = startAnimationToOverlay(fromWorkspaceState, + startAnimationToOverlay(fromWorkspaceState, Workspace.State.OVERVIEW_HIDDEN, buttonView, toView, animated, CIRCULAR_REVEAL, new PrivateTransitionCallbacks(FINAL_REVEAL_ALPHA_FOR_WIDGETS){ @Override @@ -229,7 +229,7 @@ public class LauncherStateTransitionAnimation { * Creates and starts a new animation to a particular overlay view. */ @SuppressLint("NewApi") - private AnimatorSet startAnimationToOverlay( + private void startAnimationToOverlay( final Workspace.State fromWorkspaceState, final Workspace.State toWorkspaceState, final View buttonView, final BaseContainerView toView, final boolean animated, int animType, final PrivateTransitionCallbacks pCb) { @@ -277,8 +277,7 @@ public class LauncherStateTransitionAnimation { dispatchOnLauncherTransitionStart(toView, animated, false); dispatchOnLauncherTransitionEnd(toView, animated, false); pCb.onTransitionComplete(); - - return null; + return; } if (animType == CIRCULAR_REVEAL) { // Setup the reveal view animation @@ -414,30 +413,29 @@ public class LauncherStateTransitionAnimation { toView.bringToFront(); toView.setVisibility(View.VISIBLE); toView.post(startAnimRunnable); - - return animation; + mCurrentAnimation = animation; } else if (animType == PULLUP) { // We are animating the content view alpha, so ensure we have a layer for it layerViews.put(contentView, BUILD_AND_SET_LAYER); animation.addListener(new AnimatorListenerAdapter() { - @Override - public void onAnimationEnd(Animator animation) { - dispatchOnLauncherTransitionEnd(fromView, animated, false); - dispatchOnLauncherTransitionEnd(toView, animated, false); - - // Disable all necessary layers - for (View v : layerViews.keySet()) { - if (layerViews.get(v) == BUILD_AND_SET_LAYER) { - v.setLayerType(View.LAYER_TYPE_NONE, null); - } - } - - cleanupAnimation(); - pCb.onTransitionComplete(); - } + @Override + public void onAnimationEnd(Animator animation) { + dispatchOnLauncherTransitionEnd(fromView, animated, false); + dispatchOnLauncherTransitionEnd(toView, animated, false); + + // Disable all necessary layers + for (View v : layerViews.keySet()) { + if (layerViews.get(v) == BUILD_AND_SET_LAYER) { + v.setLayerType(View.LAYER_TYPE_NONE, null); + } + } + + cleanupAnimation(); + pCb.onTransitionComplete(); + } }); - mAllAppsController.animateToAllApps(animation, revealDurationSlide); + boolean shouldPost = mAllAppsController.animateToAllApps(animation, revealDurationSlide); dispatchOnLauncherTransitionPrepare(fromView, animated, false); dispatchOnLauncherTransitionPrepare(toView, animated, false); @@ -467,10 +465,13 @@ public class LauncherStateTransitionAnimation { stateAnimation.start(); } }; - toView.post(startAnimRunnable); - return animation; + mCurrentAnimation = animation; + if (shouldPost) { + toView.post(startAnimRunnable); + } else { + startAnimRunnable.run(); + } } - return null; } /** @@ -552,7 +553,7 @@ public class LauncherStateTransitionAnimation { } }; // Only animate the search bar if animating to spring loaded mode from all apps - mCurrentAnimation = startAnimationToWorkspaceFromOverlay(fromWorkspaceState, toWorkspaceState, + startAnimationToWorkspaceFromOverlay(fromWorkspaceState, toWorkspaceState, mLauncher.getStartViewForAllAppsRevealAnimation(), appsView, animated, type, onCompleteRunnable, cb); } @@ -581,7 +582,7 @@ public class LauncherStateTransitionAnimation { mLauncher.getUserEventDispatcher().resetElapsedContainerMillis(); } }; - mCurrentAnimation = startAnimationToWorkspaceFromOverlay( + startAnimationToWorkspaceFromOverlay( fromWorkspaceState, toWorkspaceState, mLauncher.getWidgetsButton(), widgetsView, animated, CIRCULAR_REVEAL, onCompleteRunnable, cb); @@ -673,7 +674,7 @@ public class LauncherStateTransitionAnimation { /** * Creates and starts a new animation to the workspace. */ - private AnimatorSet startAnimationToWorkspaceFromOverlay( + private void startAnimationToWorkspaceFromOverlay( final Workspace.State fromWorkspaceState, final Workspace.State toWorkspaceState, final View buttonView, final BaseContainerView fromView, final boolean animated, int animType, final Runnable onCompleteRunnable, @@ -720,7 +721,7 @@ public class LauncherStateTransitionAnimation { if (onCompleteRunnable != null) { onCompleteRunnable.run(); } - return null; + return; } if (animType == CIRCULAR_REVEAL) { // hideAppsCustomizeHelper is called in some cases when it is already hidden @@ -885,9 +886,8 @@ public class LauncherStateTransitionAnimation { stateAnimation.start(); } }; + mCurrentAnimation = animation; fromView.post(startAnimRunnable); - - return animation; } else if (animType == PULLUP) { // We are animating the content view alpha, so ensure we have a layer for it layerViews.put(contentView, BUILD_AND_SET_LAYER); @@ -921,7 +921,7 @@ public class LauncherStateTransitionAnimation { } }); - mAllAppsController.animateToWorkspace(animation, revealDurationSlide); + boolean shouldPost = mAllAppsController.animateToWorkspace(animation, revealDurationSlide); // Dispatch the prepare transition signal dispatchOnLauncherTransitionPrepare(fromView, animated, multiplePagesVisible); @@ -953,10 +953,14 @@ public class LauncherStateTransitionAnimation { stateAnimation.start(); } }; - fromView.post(startAnimRunnable); - return animation; + mCurrentAnimation = animation; + if (shouldPost) { + fromView.post(startAnimRunnable); + } else { + startAnimRunnable.run(); + } } - return null; + return; } /** diff --git a/src/com/android/launcher3/allapps/AllAppsTransitionController.java b/src/com/android/launcher3/allapps/AllAppsTransitionController.java index eb6c92628..e29e4d7d8 100644 --- a/src/com/android/launcher3/allapps/AllAppsTransitionController.java +++ b/src/com/android/launcher3/allapps/AllAppsTransitionController.java @@ -18,7 +18,6 @@ import com.android.launcher3.DeviceProfile; import com.android.launcher3.Hotseat; import com.android.launcher3.Launcher; import com.android.launcher3.LauncherAnimUtils; -import com.android.launcher3.PagedView; import com.android.launcher3.R; import com.android.launcher3.Utilities; import com.android.launcher3.Workspace; @@ -44,11 +43,12 @@ public class AllAppsTransitionController implements TouchController, VerticalPul private final Interpolator mAccelInterpolator = new AccelerateInterpolator(2f); private final Interpolator mFastOutSlowInInterpolator = new FastOutSlowInInterpolator(); - private final Interpolator mScrollInterpolator = new PagedView.ScrollInterpolator(); + private final ScrollInterpolator mScrollInterpolator = new ScrollInterpolator(); private static final float ANIMATION_DURATION = 1200; - private static final float PARALLAX_COEFFICIENT = .125f; + private static final float FAST_FLING_PX_MS = 10; + private static final int SINGLE_FRAME_MS = 16; private AllAppsContainerView mAppsView; private int mAllAppsBackgroundColor; @@ -78,6 +78,7 @@ public class AllAppsTransitionController implements TouchController, VerticalPul private float mShiftRange; // changes depending on the orientation private float mProgress; // [0, 1], mShiftRange * mProgress = shiftCurrent + // Velocity of the container. Unit is in px/ms. private float mContainerVelocity; private static final float DEFAULT_SHIFT_RANGE = 10; @@ -357,7 +358,7 @@ public class AllAppsTransitionController implements TouchController, VerticalPul private void calculateDuration(float velocity, float disp) { // TODO: make these values constants after tuning. - float velocityDivisor = Math.max(1.5f, Math.abs(0.5f * velocity)); + float velocityDivisor = Math.max(2f, Math.abs(0.5f * velocity)); float travelDistance = Math.max(0.2f, disp / mShiftRange); mAnimationDuration = (long) Math.max(100, ANIMATION_DURATION / velocityDivisor * travelDistance); if (DBG) { @@ -365,22 +366,29 @@ public class AllAppsTransitionController implements TouchController, VerticalPul } } - public void animateToAllApps(AnimatorSet animationOut, long duration) { - Interpolator interpolator; + public boolean animateToAllApps(AnimatorSet animationOut, long duration) { + boolean shouldPost = true; if (animationOut == null) { - return; + return shouldPost; } + Interpolator interpolator; if (mDetector.isIdleState()) { preparePull(true); mAnimationDuration = duration; mShiftStart = mAppsView.getTranslationY(); interpolator = mFastOutSlowInInterpolator; } else { + mScrollInterpolator.setVelocityAtZero(Math.abs(mContainerVelocity)); interpolator = mScrollInterpolator; + float nextFrameProgress = mProgress + mContainerVelocity * SINGLE_FRAME_MS / mShiftRange; + if (nextFrameProgress >= 0f) { + mProgress = nextFrameProgress; + } + shouldPost = false; } - final float fromAllAppsTop = mAppsView.getTranslationY(); + ObjectAnimator driftAndAlpha = ObjectAnimator.ofFloat(this, "progress", - fromAllAppsTop / mShiftRange, 0f); + mProgress, 0f); driftAndAlpha.setDuration(mAnimationDuration); driftAndAlpha.setInterpolator(interpolator); animationOut.play(driftAndAlpha); @@ -405,6 +413,7 @@ public class AllAppsTransitionController implements TouchController, VerticalPul } }); mCurrentAnimation = animationOut; + return shouldPost; } public void showDiscoveryBounce() { @@ -437,9 +446,10 @@ public class AllAppsTransitionController implements TouchController, VerticalPul }); } - public void animateToWorkspace(AnimatorSet animationOut, long duration) { + public boolean animateToWorkspace(AnimatorSet animationOut, long duration) { + boolean shouldPost = true; if (animationOut == null) { - return; + return shouldPost; } Interpolator interpolator; if (mDetector.isIdleState()) { @@ -448,12 +458,17 @@ public class AllAppsTransitionController implements TouchController, VerticalPul mShiftStart = mAppsView.getTranslationY(); interpolator = mFastOutSlowInInterpolator; } else { + mScrollInterpolator.setVelocityAtZero(Math.abs(mContainerVelocity)); interpolator = mScrollInterpolator; + float nextFrameProgress = mProgress + mContainerVelocity * SINGLE_FRAME_MS / mShiftRange; + if (nextFrameProgress <= 1f) { + mProgress = nextFrameProgress; + } + shouldPost = false; } - final float fromAllAppsTop = mAppsView.getTranslationY(); ObjectAnimator driftAndAlpha = ObjectAnimator.ofFloat(this, "progress", - fromAllAppsTop / mShiftRange, 1f); + mProgress, 1f); driftAndAlpha.setDuration(mAnimationDuration); driftAndAlpha.setInterpolator(interpolator); animationOut.play(driftAndAlpha); @@ -478,6 +493,7 @@ public class AllAppsTransitionController implements TouchController, VerticalPul } }); mCurrentAnimation = animationOut; + return shouldPost; } public void finishPullUp() { @@ -575,4 +591,22 @@ public class AllAppsTransitionController implements TouchController, VerticalPul } setProgress(mProgress); } + + static class ScrollInterpolator implements Interpolator { + + boolean mSteeper; + + public void setVelocityAtZero(float velocity) { + mSteeper = velocity > FAST_FLING_PX_MS; + } + + public float getInterpolation(float t) { + t -= 1.0f; + float output = t * t * t; + if (mSteeper) { + output *= t * t; // Make interpolation initial slope steeper + } + return output + 1; + } + } } -- cgit v1.2.3