Merge "Adding spring animation when swiping up to home in 3P Launcher" into ub-launcher3-qt-r1-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
6f818e03a7
@@ -19,12 +19,15 @@ import static android.os.VibrationEffect.EFFECT_CLICK;
|
||||
import static android.os.VibrationEffect.createPredefined;
|
||||
|
||||
import static com.android.launcher3.Utilities.postAsyncCallback;
|
||||
import static com.android.launcher3.anim.Interpolators.ACCEL_1_5;
|
||||
import static com.android.launcher3.anim.Interpolators.DEACCEL;
|
||||
import static com.android.launcher3.config.FeatureFlags.ENABLE_QUICKSTEP_LIVE_TILE;
|
||||
import static com.android.launcher3.views.FloatingIconView.SHAPE_PROGRESS_DURATION;
|
||||
import static com.android.quickstep.TouchInteractionService.BACKGROUND_EXECUTOR;
|
||||
import static com.android.quickstep.TouchInteractionService.MAIN_THREAD_EXECUTOR;
|
||||
import static com.android.quickstep.TouchInteractionService.TOUCH_INTERACTION_LOG;
|
||||
|
||||
import android.animation.Animator;
|
||||
import android.annotation.TargetApi;
|
||||
import android.app.ActivityManager.RunningTaskInfo;
|
||||
import android.content.Context;
|
||||
@@ -32,6 +35,7 @@ import android.content.Intent;
|
||||
import android.graphics.Point;
|
||||
import android.graphics.PointF;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.RectF;
|
||||
import android.os.Build;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
@@ -48,12 +52,19 @@ import com.android.launcher3.DeviceProfile;
|
||||
import com.android.launcher3.InvariantDeviceProfile;
|
||||
import com.android.launcher3.R;
|
||||
import com.android.launcher3.Utilities;
|
||||
import com.android.launcher3.anim.AnimationSuccessListener;
|
||||
import com.android.launcher3.anim.AnimatorPlaybackController;
|
||||
import com.android.launcher3.anim.Interpolators;
|
||||
import com.android.launcher3.graphics.RotationMode;
|
||||
import com.android.launcher3.views.FloatingIconView;
|
||||
import com.android.quickstep.ActivityControlHelper.ActivityInitListener;
|
||||
import com.android.quickstep.ActivityControlHelper.HomeAnimationFactory;
|
||||
import com.android.quickstep.SysUINavigationMode.Mode;
|
||||
import com.android.quickstep.inputconsumers.InputConsumer;
|
||||
import com.android.quickstep.util.ClipAnimationHelper;
|
||||
import com.android.quickstep.util.ClipAnimationHelper.TransformParams;
|
||||
import com.android.quickstep.util.RectFSpringAnim;
|
||||
import com.android.quickstep.util.RemoteAnimationTargetSet;
|
||||
import com.android.quickstep.util.SwipeAnimationTargetSet;
|
||||
import com.android.quickstep.util.SwipeAnimationTargetSet.SwipeAnimationListener;
|
||||
import com.android.quickstep.views.RecentsView;
|
||||
@@ -369,9 +380,117 @@ public abstract class BaseSwipeUpHandler<T extends BaseDraggingActivity, Q exten
|
||||
return TaskView.getCurveScaleForInterpolation(interpolation);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an animation that transforms the current app window into the home app.
|
||||
* @param startProgress The progress of {@link #mCurrentShift} to start the window from.
|
||||
* @param homeAnimationFactory The home animation factory.
|
||||
*/
|
||||
protected RectFSpringAnim createWindowAnimationToHome(float startProgress,
|
||||
HomeAnimationFactory homeAnimationFactory) {
|
||||
final RemoteAnimationTargetSet targetSet = mRecentsAnimationWrapper.targetSet;
|
||||
final RectF startRect = new RectF(mClipAnimationHelper.applyTransform(targetSet,
|
||||
mTransformParams.setProgress(startProgress), false /* launcherOnTop */));
|
||||
final RectF targetRect = homeAnimationFactory.getWindowTargetRect();
|
||||
|
||||
final View floatingView = homeAnimationFactory.getFloatingView();
|
||||
final boolean isFloatingIconView = floatingView instanceof FloatingIconView;
|
||||
RectFSpringAnim anim = new RectFSpringAnim(startRect, targetRect, mContext.getResources());
|
||||
if (isFloatingIconView) {
|
||||
FloatingIconView fiv = (FloatingIconView) floatingView;
|
||||
anim.addAnimatorListener(fiv);
|
||||
fiv.setOnTargetChangeListener(anim::onTargetPositionChanged);
|
||||
}
|
||||
|
||||
AnimatorPlaybackController homeAnim = homeAnimationFactory.createActivityAnimationToHome();
|
||||
|
||||
// End on a "round-enough" radius so that the shape reveal doesn't have to do too much
|
||||
// rounding at the end of the animation.
|
||||
float startRadius = mClipAnimationHelper.getCurrentCornerRadius();
|
||||
float endRadius = startRect.width() / 6f;
|
||||
// We want the window alpha to be 0 once this threshold is met, so that the
|
||||
// FolderIconView can be seen morphing into the icon shape.
|
||||
final float windowAlphaThreshold = isFloatingIconView ? 1f - SHAPE_PROGRESS_DURATION : 1f;
|
||||
anim.addOnUpdateListener(new RectFSpringAnim.OnUpdateListener() {
|
||||
@Override
|
||||
public void onUpdate(RectF currentRect, float progress) {
|
||||
homeAnim.setPlayFraction(progress);
|
||||
|
||||
float alphaProgress = ACCEL_1_5.getInterpolation(progress);
|
||||
float windowAlpha = Utilities.boundToRange(Utilities.mapToRange(alphaProgress, 0,
|
||||
windowAlphaThreshold, 1.5f, 0f, Interpolators.LINEAR), 0, 1);
|
||||
mTransformParams.setProgress(progress)
|
||||
.setCurrentRectAndTargetAlpha(currentRect, windowAlpha);
|
||||
if (isFloatingIconView) {
|
||||
mTransformParams.setCornerRadius(endRadius * progress + startRadius
|
||||
* (1f - progress));
|
||||
}
|
||||
mClipAnimationHelper.applyTransform(targetSet, mTransformParams,
|
||||
false /* launcherOnTop */);
|
||||
|
||||
if (isFloatingIconView) {
|
||||
((FloatingIconView) floatingView).update(currentRect, 1f, progress,
|
||||
windowAlphaThreshold, mClipAnimationHelper.getCurrentCornerRadius(), false);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCancel() {
|
||||
if (isFloatingIconView) {
|
||||
((FloatingIconView) floatingView).fastFinish();
|
||||
}
|
||||
}
|
||||
});
|
||||
anim.addAnimatorListener(new AnimationSuccessListener() {
|
||||
@Override
|
||||
public void onAnimationStart(Animator animation) {
|
||||
homeAnim.dispatchOnStart();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAnimationSuccess(Animator animator) {
|
||||
homeAnim.getAnimationPlayer().end();
|
||||
}
|
||||
});
|
||||
return anim;
|
||||
}
|
||||
|
||||
public interface Factory {
|
||||
|
||||
BaseSwipeUpHandler newHandler(RunningTaskInfo runningTask,
|
||||
long touchTimeMs, boolean continuingLastGesture, boolean isLikelyToStartNewTask);
|
||||
}
|
||||
|
||||
protected interface RunningWindowAnim {
|
||||
void end();
|
||||
|
||||
void cancel();
|
||||
|
||||
static RunningWindowAnim wrap(Animator animator) {
|
||||
return new RunningWindowAnim() {
|
||||
@Override
|
||||
public void end() {
|
||||
animator.end();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cancel() {
|
||||
animator.cancel();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
static RunningWindowAnim wrap(RectFSpringAnim rectFSpringAnim) {
|
||||
return new RunningWindowAnim() {
|
||||
@Override
|
||||
public void end() {
|
||||
rectFSpringAnim.end();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cancel() {
|
||||
rectFSpringAnim.cancel();
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+1
-7
@@ -151,16 +151,10 @@ public final class LauncherActivityControllerHelper implements ActivityControlHe
|
||||
@NonNull
|
||||
@Override
|
||||
public RectF getWindowTargetRect() {
|
||||
final int halfIconSize = dp.iconSizePx / 2;
|
||||
final float targetCenterX = dp.availableWidthPx / 2f;
|
||||
final float targetCenterY = dp.availableHeightPx - dp.hotseatBarSizePx;
|
||||
|
||||
if (canUseWorkspaceView) {
|
||||
return iconLocation;
|
||||
} else {
|
||||
// Fallback to animate to center of screen.
|
||||
return new RectF(targetCenterX - halfIconSize, targetCenterY - halfIconSize,
|
||||
targetCenterX + halfIconSize, targetCenterY + halfIconSize);
|
||||
return HomeAnimationFactory.getDefaultWindowTargetRect(dp);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+5
-98
@@ -18,7 +18,6 @@ package com.android.quickstep;
|
||||
import static com.android.launcher3.BaseActivity.INVISIBLE_BY_STATE_HANDLER;
|
||||
import static com.android.launcher3.BaseActivity.STATE_HANDLER_INVISIBILITY_FLAGS;
|
||||
import static com.android.launcher3.Utilities.SINGLE_FRAME_MS;
|
||||
import static com.android.launcher3.anim.Interpolators.ACCEL_1_5;
|
||||
import static com.android.launcher3.anim.Interpolators.DEACCEL;
|
||||
import static com.android.launcher3.anim.Interpolators.LINEAR;
|
||||
import static com.android.launcher3.anim.Interpolators.OVERSHOOT_1_2;
|
||||
@@ -27,7 +26,6 @@ import static com.android.launcher3.config.FeatureFlags.QUICKSTEP_SPRINGS;
|
||||
import static com.android.launcher3.util.RaceConditionTracker.ENTER;
|
||||
import static com.android.launcher3.util.RaceConditionTracker.EXIT;
|
||||
import static com.android.launcher3.util.SystemUiController.UI_STATE_OVERVIEW;
|
||||
import static com.android.launcher3.views.FloatingIconView.SHAPE_PROGRESS_DURATION;
|
||||
import static com.android.quickstep.ActivityControlHelper.AnimationFactory.ShelfAnimState.HIDE;
|
||||
import static com.android.quickstep.ActivityControlHelper.AnimationFactory.ShelfAnimState.PEEK;
|
||||
import static com.android.quickstep.MultiStateCallback.DEBUG_STATES;
|
||||
@@ -52,7 +50,6 @@ import android.graphics.PointF;
|
||||
import android.graphics.RectF;
|
||||
import android.os.Build;
|
||||
import android.os.SystemClock;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import android.view.View.OnApplyWindowInsetsListener;
|
||||
import android.view.ViewTreeObserver.OnDrawListener;
|
||||
@@ -68,13 +65,11 @@ import com.android.launcher3.anim.AnimationSuccessListener;
|
||||
import com.android.launcher3.anim.AnimatorPlaybackController;
|
||||
import com.android.launcher3.anim.Interpolators;
|
||||
import com.android.launcher3.logging.UserEventDispatcher;
|
||||
import com.android.launcher3.testing.TestProtocol;
|
||||
import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Direction;
|
||||
import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Touch;
|
||||
import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType;
|
||||
import com.android.launcher3.util.RaceConditionTracker;
|
||||
import com.android.launcher3.util.TraceHelper;
|
||||
import com.android.launcher3.views.FloatingIconView;
|
||||
import com.android.quickstep.ActivityControlHelper.AnimationFactory;
|
||||
import com.android.quickstep.ActivityControlHelper.AnimationFactory.ShelfAnimState;
|
||||
import com.android.quickstep.ActivityControlHelper.HomeAnimationFactory;
|
||||
@@ -83,7 +78,6 @@ import com.android.quickstep.inputconsumers.InputConsumer;
|
||||
import com.android.quickstep.inputconsumers.OverviewInputConsumer;
|
||||
import com.android.quickstep.util.ClipAnimationHelper.TargetAlphaProvider;
|
||||
import com.android.quickstep.util.RectFSpringAnim;
|
||||
import com.android.quickstep.util.RemoteAnimationTargetSet;
|
||||
import com.android.quickstep.util.SwipeAnimationTargetSet;
|
||||
import com.android.quickstep.views.LiveTileOverlay;
|
||||
import com.android.quickstep.views.RecentsView;
|
||||
@@ -968,67 +962,15 @@ public class WindowTransformSwipeHandler<T extends BaseDraggingActivity>
|
||||
* @param startProgress The progress of {@link #mCurrentShift} to start the window from.
|
||||
* @param homeAnimationFactory The home animation factory.
|
||||
*/
|
||||
private RectFSpringAnim createWindowAnimationToHome(float startProgress,
|
||||
@Override
|
||||
protected RectFSpringAnim createWindowAnimationToHome(float startProgress,
|
||||
HomeAnimationFactory homeAnimationFactory) {
|
||||
final RemoteAnimationTargetSet targetSet = mRecentsAnimationWrapper.targetSet;
|
||||
final RectF startRect = new RectF(mClipAnimationHelper.applyTransform(targetSet,
|
||||
mTransformParams.setProgress(startProgress), false /* launcherOnTop */));
|
||||
final RectF targetRect = homeAnimationFactory.getWindowTargetRect();
|
||||
|
||||
final View floatingView = homeAnimationFactory.getFloatingView();
|
||||
final boolean isFloatingIconView = floatingView instanceof FloatingIconView;
|
||||
RectFSpringAnim anim = new RectFSpringAnim(startRect, targetRect, mActivity.getResources());
|
||||
if (isFloatingIconView) {
|
||||
FloatingIconView fiv = (FloatingIconView) floatingView;
|
||||
anim.addAnimatorListener(fiv);
|
||||
fiv.setOnTargetChangeListener(anim::onTargetPositionChanged);
|
||||
}
|
||||
|
||||
AnimatorPlaybackController homeAnim = homeAnimationFactory.createActivityAnimationToHome();
|
||||
|
||||
// End on a "round-enough" radius so that the shape reveal doesn't have to do too much
|
||||
// rounding at the end of the animation.
|
||||
float startRadius = mClipAnimationHelper.getCurrentCornerRadius();
|
||||
float endRadius = startRect.width() / 6f;
|
||||
// We want the window alpha to be 0 once this threshold is met, so that the
|
||||
// FolderIconView can be seen morphing into the icon shape.
|
||||
final float windowAlphaThreshold = isFloatingIconView ? 1f - SHAPE_PROGRESS_DURATION : 1f;
|
||||
anim.addOnUpdateListener(new RectFSpringAnim.OnUpdateListener() {
|
||||
@Override
|
||||
public void onUpdate(RectF currentRect, float progress) {
|
||||
homeAnim.setPlayFraction(progress);
|
||||
|
||||
float alphaProgress = ACCEL_1_5.getInterpolation(progress);
|
||||
float windowAlpha = Utilities.boundToRange(Utilities.mapToRange(alphaProgress, 0,
|
||||
windowAlphaThreshold, 1.5f, 0f, Interpolators.LINEAR), 0, 1);
|
||||
mTransformParams.setProgress(progress)
|
||||
.setCurrentRectAndTargetAlpha(currentRect, windowAlpha);
|
||||
if (isFloatingIconView) {
|
||||
mTransformParams.setCornerRadius(endRadius * progress + startRadius
|
||||
* (1f - progress));
|
||||
}
|
||||
mClipAnimationHelper.applyTransform(targetSet, mTransformParams,
|
||||
false /* launcherOnTop */);
|
||||
|
||||
if (isFloatingIconView) {
|
||||
((FloatingIconView) floatingView).update(currentRect, 1f, progress,
|
||||
windowAlphaThreshold, mClipAnimationHelper.getCurrentCornerRadius(), false);
|
||||
}
|
||||
|
||||
updateSysUiFlags(Math.max(progress, mCurrentShift.value));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCancel() {
|
||||
if (isFloatingIconView) {
|
||||
((FloatingIconView) floatingView).fastFinish();
|
||||
}
|
||||
}
|
||||
});
|
||||
RectFSpringAnim anim =
|
||||
super.createWindowAnimationToHome(startProgress, homeAnimationFactory);
|
||||
anim.addOnUpdateListener((r, p) -> updateSysUiFlags(Math.max(p, mCurrentShift.value)));
|
||||
anim.addAnimatorListener(new AnimationSuccessListener() {
|
||||
@Override
|
||||
public void onAnimationStart(Animator animation) {
|
||||
homeAnim.dispatchOnStart();
|
||||
if (mActivity != null) {
|
||||
mActivity.getRootView().getOverlay().remove(mLiveTileOverlay);
|
||||
}
|
||||
@@ -1036,7 +978,6 @@ public class WindowTransformSwipeHandler<T extends BaseDraggingActivity>
|
||||
|
||||
@Override
|
||||
public void onAnimationSuccess(Animator animator) {
|
||||
homeAnim.getAnimationPlayer().end();
|
||||
if (mRecentsView != null) {
|
||||
mRecentsView.post(mRecentsView::resetTaskVisuals);
|
||||
}
|
||||
@@ -1270,38 +1211,4 @@ public class WindowTransformSwipeHandler<T extends BaseDraggingActivity>
|
||||
return app.isNotInRecents
|
||||
|| app.activityType == RemoteAnimationTargetCompat.ACTIVITY_TYPE_HOME;
|
||||
}
|
||||
|
||||
private interface RunningWindowAnim {
|
||||
void end();
|
||||
|
||||
void cancel();
|
||||
|
||||
static RunningWindowAnim wrap(Animator animator) {
|
||||
return new RunningWindowAnim() {
|
||||
@Override
|
||||
public void end() {
|
||||
animator.end();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cancel() {
|
||||
animator.cancel();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
static RunningWindowAnim wrap(RectFSpringAnim rectFSpringAnim) {
|
||||
return new RunningWindowAnim() {
|
||||
@Override
|
||||
public void end() {
|
||||
rectFSpringAnim.end();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cancel() {
|
||||
rectFSpringAnim.cancel();
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+62
-22
@@ -18,11 +18,12 @@ package com.android.quickstep.inputconsumers;
|
||||
import static com.android.quickstep.MultiStateCallback.DEBUG_STATES;
|
||||
import static com.android.quickstep.RecentsActivity.EXTRA_TASK_ID;
|
||||
import static com.android.quickstep.RecentsActivity.EXTRA_THUMBNAIL;
|
||||
import static com.android.quickstep.inputconsumers.FallbackNoButtonInputConsumer.GestureEndTarget.NEW_TASK;
|
||||
import static com.android.quickstep.WindowTransformSwipeHandler.MIN_PROGRESS_FOR_OVERVIEW;
|
||||
import static com.android.quickstep.inputconsumers.FallbackNoButtonInputConsumer.GestureEndTarget.HOME;
|
||||
import static com.android.quickstep.inputconsumers.FallbackNoButtonInputConsumer.GestureEndTarget.LAST_TASK;
|
||||
import static com.android.quickstep.inputconsumers.FallbackNoButtonInputConsumer.GestureEndTarget.NEW_TASK;
|
||||
import static com.android.quickstep.inputconsumers.FallbackNoButtonInputConsumer.GestureEndTarget.RECENTS;
|
||||
import static com.android.quickstep.views.RecentsView.UPDATE_SYSUI_FLAGS_THRESHOLD;
|
||||
|
||||
import android.animation.Animator;
|
||||
import android.animation.AnimatorSet;
|
||||
@@ -31,10 +32,13 @@ import android.app.ActivityOptions;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.graphics.PointF;
|
||||
import android.graphics.RectF;
|
||||
import android.os.Bundle;
|
||||
|
||||
import com.android.launcher3.R;
|
||||
import com.android.launcher3.anim.AnimationSuccessListener;
|
||||
import com.android.launcher3.anim.AnimatorPlaybackController;
|
||||
import com.android.quickstep.ActivityControlHelper.HomeAnimationFactory;
|
||||
import com.android.quickstep.AnimatedFloat;
|
||||
import com.android.quickstep.BaseSwipeUpHandler;
|
||||
import com.android.quickstep.MultiStateCallback;
|
||||
@@ -44,6 +48,7 @@ import com.android.quickstep.RecentsModel;
|
||||
import com.android.quickstep.SwipeSharedState;
|
||||
import com.android.quickstep.fallback.FallbackRecentsView;
|
||||
import com.android.quickstep.util.ObjectWrapper;
|
||||
import com.android.quickstep.util.RectFSpringAnim;
|
||||
import com.android.quickstep.util.SwipeAnimationTargetSet;
|
||||
import com.android.quickstep.views.TaskView;
|
||||
import com.android.systemui.shared.recents.model.ThumbnailData;
|
||||
@@ -102,10 +107,10 @@ public class FallbackNoButtonInputConsumer extends
|
||||
private final boolean mRunningOverHome;
|
||||
private final boolean mSwipeUpOverHome;
|
||||
|
||||
|
||||
private final RunningTaskInfo mRunningTaskInfo;
|
||||
|
||||
private Animator mFinishAnimation;
|
||||
private final PointF mEndVelocityPxPerMs = new PointF(0, 0.5f);
|
||||
private RunningWindowAnim mFinishAnimation;
|
||||
|
||||
public FallbackNoButtonInputConsumer(Context context,
|
||||
OverviewComponentObserver overviewComponentObserver,
|
||||
@@ -226,6 +231,8 @@ public class FallbackNoButtonInputConsumer extends
|
||||
@Override
|
||||
public void updateFinalShift() {
|
||||
mTransformParams.setProgress(mCurrentShift.value);
|
||||
mRecentsAnimationWrapper.setWindowThresholdCrossed(!mInQuickSwitchMode
|
||||
&& (mCurrentShift.value > 1 - UPDATE_SYSUI_FLAGS_THRESHOLD));
|
||||
if (mRecentsAnimationWrapper.targetSet != null) {
|
||||
applyTransformUnchecked();
|
||||
}
|
||||
@@ -240,6 +247,7 @@ public class FallbackNoButtonInputConsumer extends
|
||||
|
||||
@Override
|
||||
public void onGestureEnded(float endVelocity, PointF velocity, PointF downPos) {
|
||||
mEndVelocityPxPerMs.set(0, velocity.y / 1000);
|
||||
if (mInQuickSwitchMode) {
|
||||
// For now set it to non-null, it will be reset before starting the animation
|
||||
mEndTarget = LAST_TASK;
|
||||
@@ -288,12 +296,14 @@ public class FallbackNoButtonInputConsumer extends
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void onHandlerInvalidated() {
|
||||
mActivityInitListener.unregister();
|
||||
if (mGestureEndCallback != null) {
|
||||
mGestureEndCallback.run();
|
||||
}
|
||||
if (mFinishAnimation != null) {
|
||||
mFinishAnimation.end();
|
||||
}
|
||||
}
|
||||
|
||||
private void onHandlerInvalidatedWithRecents() {
|
||||
@@ -364,31 +374,39 @@ public class FallbackNoButtonInputConsumer extends
|
||||
}
|
||||
|
||||
float endProgress = mEndTarget.mEndProgress;
|
||||
|
||||
long duration = (long) (mEndTarget.mDurationMultiplier *
|
||||
Math.abs(endProgress - mCurrentShift.value));
|
||||
if (mRecentsView != null) {
|
||||
duration = Math.max(duration, mRecentsView.getScroller().getDuration());
|
||||
}
|
||||
if (mCurrentShift.value != endProgress || mInQuickSwitchMode) {
|
||||
AnimatorSet anim = new AnimatorSet();
|
||||
anim.play(mLauncherAlpha.animateToValue(
|
||||
mLauncherAlpha.value, mEndTarget.mLauncherAlpha));
|
||||
anim.play(mCurrentShift.animateToValue(mCurrentShift.value, endProgress));
|
||||
|
||||
|
||||
long duration = (long) (mEndTarget.mDurationMultiplier *
|
||||
Math.abs(endProgress - mCurrentShift.value));
|
||||
if (mRecentsView != null) {
|
||||
duration = Math.max(duration, mRecentsView.getScroller().getDuration());
|
||||
}
|
||||
|
||||
anim.setDuration(duration);
|
||||
anim.addListener(new AnimationSuccessListener() {
|
||||
AnimationSuccessListener endListener = new AnimationSuccessListener() {
|
||||
|
||||
@Override
|
||||
public void onAnimationSuccess(Animator animator) {
|
||||
finishAnimationTargetSetAnimationComplete();
|
||||
mFinishAnimation = null;
|
||||
}
|
||||
});
|
||||
anim.start();
|
||||
mFinishAnimation = anim;
|
||||
};
|
||||
|
||||
if (mEndTarget == HOME && !mRunningOverHome) {
|
||||
RectFSpringAnim anim = createWindowAnimationToHome(mCurrentShift.value, duration);
|
||||
anim.addAnimatorListener(endListener);
|
||||
anim.start(mEndVelocityPxPerMs);
|
||||
mFinishAnimation = RunningWindowAnim.wrap(anim);
|
||||
} else {
|
||||
|
||||
AnimatorSet anim = new AnimatorSet();
|
||||
anim.play(mLauncherAlpha.animateToValue(
|
||||
mLauncherAlpha.value, mEndTarget.mLauncherAlpha));
|
||||
anim.play(mCurrentShift.animateToValue(mCurrentShift.value, endProgress));
|
||||
|
||||
anim.setDuration(duration);
|
||||
anim.addListener(endListener);
|
||||
anim.start();
|
||||
mFinishAnimation = RunningWindowAnim.wrap(anim);
|
||||
}
|
||||
|
||||
} else {
|
||||
finishAnimationTargetSetAnimationComplete();
|
||||
}
|
||||
@@ -412,4 +430,26 @@ public class FallbackNoButtonInputConsumer extends
|
||||
mRecentsAnimationWrapper.setController(null);
|
||||
setStateOnUiThread(STATE_HANDLER_INVALIDATED);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an animation that transforms the current app window into the home app.
|
||||
* @param startProgress The progress of {@link #mCurrentShift} to start the window from.
|
||||
*/
|
||||
private RectFSpringAnim createWindowAnimationToHome(float startProgress, long duration) {
|
||||
HomeAnimationFactory factory = new HomeAnimationFactory() {
|
||||
@Override
|
||||
public RectF getWindowTargetRect() {
|
||||
return HomeAnimationFactory.getDefaultWindowTargetRect(mDp);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AnimatorPlaybackController createActivityAnimationToHome() {
|
||||
AnimatorSet anim = new AnimatorSet();
|
||||
anim.play(mLauncherAlpha.animateToValue(mLauncherAlpha.value, 1));
|
||||
anim.setDuration(duration);
|
||||
return AnimatorPlaybackController.wrap(anim, duration);
|
||||
}
|
||||
};
|
||||
return createWindowAnimationToHome(startProgress, factory);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -237,6 +237,6 @@ public class RectFSpringAnim {
|
||||
public interface OnUpdateListener {
|
||||
void onUpdate(RectF currentRect, float progress);
|
||||
|
||||
void onCancel();
|
||||
default void onCancel() { }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -152,5 +152,15 @@ public interface ActivityControlHelper<T extends BaseDraggingActivity> {
|
||||
default void playAtomicAnimation(float velocity) {
|
||||
// No-op
|
||||
}
|
||||
|
||||
static RectF getDefaultWindowTargetRect(DeviceProfile dp) {
|
||||
final int halfIconSize = dp.iconSizePx / 2;
|
||||
final float targetCenterX = dp.availableWidthPx / 2f;
|
||||
final float targetCenterY = dp.availableHeightPx - dp.hotseatBarSizePx;
|
||||
// Fallback to animate to center of screen.
|
||||
return new RectF(targetCenterX - halfIconSize, targetCenterY - halfIconSize,
|
||||
targetCenterX + halfIconSize, targetCenterY + halfIconSize);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user