Animate TaskView as you swipe down on it to launch

Bug: 73835352
Change-Id: Ia255a7af8fb6cd972f99de6390e097afc29c1b90
This commit is contained in:
Tony Wickham
2018-03-29 09:39:56 -07:00
parent 7a802eb6db
commit 3a6746ac04
5 changed files with 92 additions and 35 deletions

View File

@@ -148,14 +148,7 @@ public class LauncherAppTransitionManagerImpl extends LauncherAppTransitionManag
@Override
public AnimatorSet getAnimator(RemoteAnimationTargetCompat[] targetCompats) {
Animator[] anims = composeRecentsLaunchAnimator(v, targetCompats);
AnimatorSet anim = new AnimatorSet();
if (anims != null) {
anim.playTogether(anims);
} else {
anim.play(getLauncherAnimators(v, targetCompats));
anim.play(getWindowAnimators(v, targetCompats));
}
AnimatorSet anim = createLaunchAnimatorForView(v, targetCompats);
mLauncher.getStateManager().setCurrentAnimation(anim);
return anim;
}
@@ -174,6 +167,19 @@ public class LauncherAppTransitionManagerImpl extends LauncherAppTransitionManag
return getDefaultActivityLaunchOptions(launcher, v);
}
private AnimatorSet createLaunchAnimatorForView(View v, RemoteAnimationTargetCompat[] targets) {
Animator[] anims = composeRecentsLaunchAnimator(v, new AnimConfig(targets,
RECENTS_LAUNCH_DURATION, Interpolators.TOUCH_RESPONSE_INTERPOLATOR));
AnimatorSet anim = new AnimatorSet();
if (anims != null) {
anim.playTogether(anims);
} else {
anim.play(getLauncherAnimators(v, targets));
anim.play(getWindowAnimators(v, targets));
}
return anim;
}
/**
* Try to find a TaskView that corresponds with the component of the launched view.
*
@@ -232,21 +238,32 @@ public class LauncherAppTransitionManagerImpl extends LauncherAppTransitionManag
return taskView;
}
public AnimatorSet composeUserControlledRecentsLaunchAnimator(TaskView v, AnimConfig config) {
Animator[] anims = composeRecentsLaunchAnimator(v, config);
AnimatorSet anim = new AnimatorSet();
anim.playTogether(anims);
return anim;
}
/**
* Composes the animations for a launch from the recents list if possible.
*/
private Animator[] composeRecentsLaunchAnimator(View v,
RemoteAnimationTargetCompat[] targets) {
private Animator[] composeRecentsLaunchAnimator(View v, AnimConfig config) {
// Ensure recents is actually visible
if (!mLauncher.getStateManager().getState().overviewUi) {
return null;
}
RecentsView recentsView = mLauncher.getOverviewPanel();
boolean launcherClosing = launcherIsATargetWithMode(targets, MODE_CLOSING);
boolean launcherClosing = launcherIsATargetWithMode(config.targets, MODE_CLOSING);
if (config.userControlled) {
// We don't pass any targets when creating a user-controlled animation. In this case,
// assume launcher is closing.
launcherClosing = true;
}
boolean skipLauncherChanges = !launcherClosing;
TaskView taskView = findTaskViewToLaunch(mLauncher, v, targets);
TaskView taskView = findTaskViewToLaunch(mLauncher, v, config.targets);
if (taskView == null) {
return null;
}
@@ -255,7 +272,7 @@ public class LauncherAppTransitionManagerImpl extends LauncherAppTransitionManag
Animator launcherAnim;
final AnimatorListenerAdapter windowAnimEndListener;
if (launcherClosing) {
launcherAnim = getRecentsLauncherAnimator(recentsView, taskView);
launcherAnim = getRecentsLauncherAnimator(recentsView, taskView, config);
// Make sure recents gets fixed up by resetting task alphas and scales, etc.
windowAnimEndListener = mReapplyStateListener;
} else {
@@ -272,8 +289,12 @@ public class LauncherAppTransitionManagerImpl extends LauncherAppTransitionManag
};
}
Animator windowAnim = getRecentsWindowAnimator(taskView, skipLauncherChanges, targets);
windowAnim.addListener(windowAnimEndListener);
Animator windowAnim = getRecentsWindowAnimator(taskView, skipLauncherChanges, config);
if (!config.userControlled) {
// Don't reset properties if the animation is user-controlled, as we will run the
// "real" (not user controlled) animation from where they left off when they let go.
windowAnim.addListener(windowAnimEndListener);
}
return new Animator[] {launcherAnim, windowAnim};
}
@@ -283,7 +304,8 @@ public class LauncherAppTransitionManagerImpl extends LauncherAppTransitionManag
* If launching one of the adjacent tasks, parallax the center task and other adjacent task
* to the right.
*/
private Animator getRecentsLauncherAnimator(RecentsView recentsView, TaskView v) {
private Animator getRecentsLauncherAnimator(RecentsView recentsView, TaskView v,
AnimConfig config) {
AnimatorSet launcherAnimator = new AnimatorSet();
int launchedTaskIndex = recentsView.indexOfChild(v);
@@ -307,6 +329,8 @@ public class LauncherAppTransitionManagerImpl extends LauncherAppTransitionManag
.translationY(toTranslationY)
.translationX(isRtl ? displacementX : -displacementX)
.build());
adjacentTask1ScaleAndTranslate.setInterpolator(config.interpolator);
adjacentTask1ScaleAndTranslate.setDuration(config.duration);
launcherAnimator.play(adjacentTask1ScaleAndTranslate);
}
if (launchedTaskIndex + 1 < recentsView.getPageCount()) {
@@ -318,6 +342,8 @@ public class LauncherAppTransitionManagerImpl extends LauncherAppTransitionManag
.translationY(toTranslationY)
.translationX(isRtl ? -displacementX : displacementX)
.build());
adjacentTask2ScaleAndTranslate.setInterpolator(config.interpolator);
adjacentTask2ScaleAndTranslate.setDuration(config.duration);
launcherAnimator.play(adjacentTask2ScaleAndTranslate);
}
} else {
@@ -328,6 +354,8 @@ public class LauncherAppTransitionManagerImpl extends LauncherAppTransitionManag
new PropertyListBuilder()
.translationX(isRtl ? -displacementX : displacementX)
.build());
centerTaskParallaxOffscreen.setInterpolator(config.interpolator);
centerTaskParallaxOffscreen.setDuration(config.duration);
launcherAnimator.play(centerTaskParallaxOffscreen);
int otherAdjacentTaskIndex = centerTaskIndex + (centerTaskIndex - launchedTaskIndex);
if (otherAdjacentTaskIndex >= 0
@@ -340,6 +368,8 @@ public class LauncherAppTransitionManagerImpl extends LauncherAppTransitionManag
.translationX(isRtl ? -displacementX : displacementX)
.scale(1)
.build());
otherAdjacentTaskParallaxOffscreen.setInterpolator(config.interpolator);
otherAdjacentTaskParallaxOffscreen.setDuration(config.duration);
launcherAnimator.play(otherAdjacentTaskParallaxOffscreen);
}
}
@@ -353,6 +383,8 @@ public class LauncherAppTransitionManagerImpl extends LauncherAppTransitionManag
}
Animator allAppsSlideOut = ObjectAnimator.ofFloat(mLauncher.getAllAppsController(),
ALL_APPS_PROGRESS, allAppsProgressOffscreen);
allAppsSlideOut.setInterpolator(config.interpolator);
allAppsSlideOut.setDuration(config.duration);
launcherAnimator.play(allAppsSlideOut);
Workspace workspace = mLauncher.getWorkspace();
@@ -363,12 +395,12 @@ public class LauncherAppTransitionManagerImpl extends LauncherAppTransitionManag
.translationX(workspaceScaleAndTranslation[1])
.translationY(workspaceScaleAndTranslation[2])
.build());
recenterWorkspace.setInterpolator(config.interpolator);
recenterWorkspace.setDuration(config.duration);
launcherAnimator.play(recenterWorkspace);
CellLayout currentWorkspacePage = (CellLayout) workspace.getPageAt(
workspace.getCurrentPage());
launcherAnimator.setInterpolator(Interpolators.TOUCH_RESPONSE_INTERPOLATOR);
launcherAnimator.setDuration(RECENTS_LAUNCH_DURATION);
return launcherAnimator;
}
@@ -392,15 +424,15 @@ public class LauncherAppTransitionManagerImpl extends LauncherAppTransitionManag
* animation.
*/
private ValueAnimator getRecentsWindowAnimator(TaskView v, boolean skipLauncherChanges,
RemoteAnimationTargetCompat[] targets) {
AnimConfig config) {
final RecentsAnimationInterpolator recentsInterpolator = getRecentsInterpolator(v);
Rect crop = new Rect();
Matrix matrix = new Matrix();
ValueAnimator appAnimator = ValueAnimator.ofFloat(0, 1);
appAnimator.setDuration(RECENTS_LAUNCH_DURATION);
appAnimator.setInterpolator(Interpolators.TOUCH_RESPONSE_INTERPOLATOR);
appAnimator.setDuration(config.duration);
appAnimator.setInterpolator(config.interpolator);
appAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
boolean isFirstFrame = true;
@@ -416,14 +448,17 @@ public class LauncherAppTransitionManagerImpl extends LauncherAppTransitionManag
final float percent = animation.getAnimatedFraction();
TaskWindowBounds tw = recentsInterpolator.interpolate(percent);
float alphaDuration = 75;
if (!skipLauncherChanges) {
v.setScaleX(tw.taskScale);
v.setScaleY(tw.taskScale);
v.setTranslationX(tw.taskX);
v.setTranslationY(tw.taskY);
// Defer fading out the view until after the app window gets faded in
v.setAlpha(getValue(1f, 0f, 75, 75,
appAnimator.getDuration() * percent, Interpolators.LINEAR));
if (!config.userControlled) {
// Defer fading out the view until after the app window gets faded in
v.setAlpha(getValue(1f, 0f, alphaDuration, alphaDuration,
appAnimator.getDuration() * percent, Interpolators.LINEAR));
}
}
matrix.setScale(tw.winScale, tw.winScale);
@@ -431,12 +466,11 @@ public class LauncherAppTransitionManagerImpl extends LauncherAppTransitionManag
crop.set(tw.winCrop);
// Fade in the app window.
float alphaDuration = 75;
float alpha = getValue(0f, 1f, 0, alphaDuration,
appAnimator.getDuration() * percent, Interpolators.LINEAR);
TransactionCompat t = new TransactionCompat();
for (RemoteAnimationTargetCompat target : targets) {
for (RemoteAnimationTargetCompat target : config.targets) {
if (target.mode == RemoteAnimationTargetCompat.MODE_OPENING) {
t.setAlpha(target.leash, alpha);
@@ -933,4 +967,24 @@ public class LauncherAppTransitionManagerImpl extends LauncherAppTransitionManag
newPercent = i.getInterpolation(newPercent);
return end * newPercent + start * (1 - newPercent);
}
public static class AnimConfig {
public RemoteAnimationTargetCompat[] targets;
public long duration;
public Interpolator interpolator;
public boolean userControlled = false;
public AnimConfig(RemoteAnimationTargetCompat[] targets, long duration,
Interpolator interpolator) {
this.targets = targets;
this.duration = duration;
this.interpolator = interpolator;
}
public AnimConfig(long duration, Interpolator interpolator) {
this(new RemoteAnimationTargetCompat[0], duration, interpolator);
userControlled = true;
}
}
}

View File

@@ -28,8 +28,11 @@ import android.view.View;
import com.android.launcher3.AbstractFloatingView;
import com.android.launcher3.Launcher;
import com.android.launcher3.LauncherAppTransitionManagerImpl;
import com.android.launcher3.LauncherAppTransitionManagerImpl.AnimConfig;
import com.android.launcher3.Utilities;
import com.android.launcher3.anim.AnimatorPlaybackController;
import com.android.launcher3.anim.Interpolators;
import com.android.launcher3.dragndrop.DragLayer;
import com.android.launcher3.touch.SwipeDetector;
import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Direction;
@@ -167,8 +170,10 @@ public class TaskViewTouchController extends AnimatorListenerAdapter
.wrap(mPendingAnimation.anim, maxDuration);
mEndDisplacement = -mTaskBeingDragged.getHeight();
} else {
AnimatorSet anim = new AnimatorSet();
// TODO: Setup a zoom animation
LauncherAppTransitionManagerImpl appTransitionManager =
(LauncherAppTransitionManagerImpl) mLauncher.getAppTransitionManager();
AnimatorSet anim = appTransitionManager.composeUserControlledRecentsLaunchAnimator(
mTaskBeingDragged, new AnimConfig(maxDuration, Interpolators.ZOOM_IN));
mCurrentAnimation = AnimatorPlaybackController.wrap(anim, maxDuration);
mTempCords[1] = mTaskBeingDragged.getHeight();

View File

@@ -26,7 +26,6 @@ import android.util.AttributeSet;
import android.util.FloatProperty;
import android.view.View;
import android.view.ViewDebug;
import android.widget.FrameLayout;
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.Insettable;
@@ -92,11 +91,7 @@ public class LauncherRecentsView extends RecentsView<Launcher> implements Insett
mInsets.set(insets);
DeviceProfile dp = mActivity.getDeviceProfile();
Rect padding = getPadding(dp, getContext());
FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) getLayoutParams();
lp.bottomMargin = padding.bottom;
setLayoutParams(lp);
setPadding(padding.left, padding.top, padding.right, 0);
setPadding(padding.left, padding.top, padding.right, padding.bottom);
mPagePadding.set(padding);
mPagePadding.top += getResources().getDimensionPixelSize(R.dimen.task_thumbnail_top_margin);
}

View File

@@ -1684,6 +1684,10 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns, L
: mAppTransitionManager.getActivityLaunchOptions(this, v);
}
public LauncherAppTransitionManager getAppTransitionManager() {
return mAppTransitionManager;
}
@TargetApi(Build.VERSION_CODES.M)
@Override
protected boolean onErrorStartingShortcut(Intent intent, ItemInfo info) {

View File

@@ -206,7 +206,6 @@ public abstract class AnimatorPlaybackController implements ValueAnimator.Animat
anim.setCurrentPlayTime(Math.min(playPos, anim.getDuration()));
}
}
}
private class OnAnimationEndDispatcher extends AnimationSuccessListener {