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
This commit is contained in:
Hyunyoung Song
2016-08-03 15:14:43 -07:00
parent b9b54efd59
commit 191e9d1b29
2 changed files with 85 additions and 47 deletions
@@ -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);
@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);
}
}
// 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();
}
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;
}
/**
@@ -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;
}
}
}