Merge "Fixing task open animation in split screen mode" into ub-launcher3-edmonton
This commit is contained in:
commit
6dcf142f61
|
@ -64,6 +64,7 @@ import com.android.launcher3.anim.Interpolators;
|
|||
import com.android.launcher3.dragndrop.DragLayer;
|
||||
import com.android.launcher3.graphics.DrawableFactory;
|
||||
import com.android.launcher3.shortcuts.DeepShortcutView;
|
||||
import com.android.quickstep.util.ClipAnimationHelper;
|
||||
import com.android.quickstep.util.MultiValueUpdateListener;
|
||||
import com.android.quickstep.util.RemoteAnimationProvider;
|
||||
import com.android.quickstep.views.RecentsView;
|
||||
|
@ -233,12 +234,16 @@ public class LauncherAppTransitionManagerImpl extends LauncherAppTransitionManag
|
|||
return false;
|
||||
}
|
||||
|
||||
ClipAnimationHelper helper = new ClipAnimationHelper();
|
||||
target.play(getRecentsWindowAnimator(taskView, skipLauncherChanges, targets, helper)
|
||||
.setDuration(RECENTS_LAUNCH_DURATION));
|
||||
|
||||
Animator childStateAnimation = null;
|
||||
// Found a visible recents task that matches the opening app, lets launch the app from there
|
||||
Animator launcherAnim;
|
||||
final AnimatorListenerAdapter windowAnimEndListener;
|
||||
if (launcherClosing) {
|
||||
launcherAnim = recentsView.createAdjacentPageAnimForTaskLaunch(taskView);
|
||||
launcherAnim = recentsView.createAdjacentPageAnimForTaskLaunch(taskView, helper);
|
||||
launcherAnim.setInterpolator(Interpolators.TOUCH_RESPONSE_INTERPOLATOR);
|
||||
launcherAnim.setDuration(RECENTS_LAUNCH_DURATION);
|
||||
|
||||
|
@ -258,9 +263,6 @@ public class LauncherAppTransitionManagerImpl extends LauncherAppTransitionManag
|
|||
}
|
||||
};
|
||||
}
|
||||
|
||||
target.play(getRecentsWindowAnimator(taskView, skipLauncherChanges, targets)
|
||||
.setDuration(RECENTS_LAUNCH_DURATION));
|
||||
target.play(launcherAnim);
|
||||
|
||||
// Set the current animation first, before adding windowAnimEndListener. Setting current
|
||||
|
|
|
@ -51,6 +51,7 @@ import com.android.launcher3.util.Themes;
|
|||
import com.android.launcher3.views.BaseDragLayer;
|
||||
import com.android.quickstep.fallback.FallbackRecentsView;
|
||||
import com.android.quickstep.fallback.RecentsRootView;
|
||||
import com.android.quickstep.util.ClipAnimationHelper;
|
||||
import com.android.quickstep.views.RecentsViewContainer;
|
||||
import com.android.quickstep.views.TaskView;
|
||||
import com.android.systemui.shared.system.ActivityOptionsCompat;
|
||||
|
@ -193,13 +194,14 @@ public class RecentsActivity extends BaseDraggingActivity {
|
|||
RemoteAnimationTargetCompat[] targets) {
|
||||
AnimatorSet target = new AnimatorSet();
|
||||
boolean activityClosing = taskIsATargetWithMode(targets, getTaskId(), MODE_CLOSING);
|
||||
target.play(getRecentsWindowAnimator(taskView, !activityClosing, targets)
|
||||
ClipAnimationHelper helper = new ClipAnimationHelper();
|
||||
target.play(getRecentsWindowAnimator(taskView, !activityClosing, targets, helper)
|
||||
.setDuration(RECENTS_LAUNCH_DURATION));
|
||||
|
||||
// Found a visible recents task that matches the opening app, lets launch the app from there
|
||||
if (activityClosing) {
|
||||
Animator adjacentAnimation = mFallbackRecentsView
|
||||
.createAdjacentPageAnimForTaskLaunch(taskView);
|
||||
.createAdjacentPageAnimForTaskLaunch(taskView, helper);
|
||||
adjacentAnimation.setInterpolator(Interpolators.TOUCH_RESPONSE_INTERPOLATOR);
|
||||
adjacentAnimation.setDuration(RECENTS_LAUNCH_DURATION);
|
||||
adjacentAnimation.addListener(new AnimatorListenerAdapter() {
|
||||
|
|
|
@ -1,117 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2018 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.android.quickstep;
|
||||
|
||||
import android.graphics.Rect;
|
||||
|
||||
import com.android.launcher3.Utilities;
|
||||
|
||||
/**
|
||||
* Helper class to interpolate the animation between a task view representation and an actual
|
||||
* window.
|
||||
*/
|
||||
public class RecentsAnimationInterpolator {
|
||||
|
||||
public static class TaskWindowBounds {
|
||||
public float taskScale = 1f;
|
||||
public float taskX = 0f;
|
||||
public float taskY = 0f;
|
||||
|
||||
public float winScale = 1f;
|
||||
public float winX = 0f;
|
||||
public float winY = 0f;
|
||||
public Rect winCrop = new Rect();
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "taskScale=" + taskScale + " taskX=" + taskX + " taskY=" + taskY
|
||||
+ " winScale=" + winScale + " winX=" + winX + " winY=" + winY
|
||||
+ " winCrop=" + winCrop;
|
||||
}
|
||||
}
|
||||
|
||||
private TaskWindowBounds mTmpTaskWindowBounds = new TaskWindowBounds();
|
||||
private Rect mTmpInsets = new Rect();
|
||||
|
||||
private Rect mWindow;
|
||||
private Rect mInsetWindow;
|
||||
private Rect mInsets;
|
||||
private Rect mTask;
|
||||
private Rect mTaskInsets;
|
||||
private Rect mThumbnail;
|
||||
|
||||
private float mInitialTaskScale;
|
||||
private float mInitialTaskTranslationX;
|
||||
private float mFinalTaskScale;
|
||||
private Rect mScaledTask;
|
||||
private Rect mTargetTask;
|
||||
private Rect mSrcWindow;
|
||||
|
||||
public RecentsAnimationInterpolator(Rect window, Rect insets, Rect task, Rect taskInsets,
|
||||
float taskScale, float taskTranslationX) {
|
||||
mWindow = window;
|
||||
mInsets = insets;
|
||||
mTask = task;
|
||||
mTaskInsets = taskInsets;
|
||||
mInsetWindow = new Rect(window);
|
||||
Utilities.insetRect(mInsetWindow, insets);
|
||||
|
||||
mThumbnail = new Rect(task);
|
||||
Utilities.insetRect(mThumbnail, taskInsets);
|
||||
mInitialTaskScale = taskScale;
|
||||
mInitialTaskTranslationX = taskTranslationX;
|
||||
mFinalTaskScale = (float) mInsetWindow.width() / mThumbnail.width();
|
||||
mScaledTask = new Rect(task);
|
||||
Utilities.scaleRectAboutCenter(mScaledTask, mFinalTaskScale);
|
||||
Rect finalScaledTaskInsets = new Rect(taskInsets);
|
||||
Utilities.scaleRect(finalScaledTaskInsets, mFinalTaskScale);
|
||||
mTargetTask = new Rect(mInsetWindow);
|
||||
mTargetTask.offsetTo(window.left + insets.left - finalScaledTaskInsets.left,
|
||||
window.top + insets.top - finalScaledTaskInsets.top);
|
||||
|
||||
float initialWinScale = 1f / mFinalTaskScale;
|
||||
Rect scaledWindow = new Rect(mInsetWindow);
|
||||
Utilities.scaleRectAboutCenter(scaledWindow, initialWinScale);
|
||||
Rect scaledInsets = new Rect(insets);
|
||||
Utilities.scaleRect(scaledInsets, initialWinScale);
|
||||
mSrcWindow = new Rect(scaledWindow);
|
||||
mSrcWindow.offsetTo(mThumbnail.left - scaledInsets.left,
|
||||
mThumbnail.top - scaledInsets.top);
|
||||
}
|
||||
|
||||
public TaskWindowBounds interpolate(float t) {
|
||||
mTmpTaskWindowBounds.taskScale = Utilities.mapRange(t,
|
||||
mInitialTaskScale, mFinalTaskScale);
|
||||
mTmpTaskWindowBounds.taskX = Utilities.mapRange(t,
|
||||
mInitialTaskTranslationX, mTargetTask.left - mScaledTask.left);
|
||||
mTmpTaskWindowBounds.taskY = Utilities.mapRange(t,
|
||||
0, mTargetTask.top - mScaledTask.top);
|
||||
|
||||
float taskScale = Utilities.mapRange(t, 1, mFinalTaskScale);
|
||||
mTmpTaskWindowBounds.winScale = taskScale / mFinalTaskScale;
|
||||
mTmpTaskWindowBounds.winX = Utilities.mapRange(t,
|
||||
mSrcWindow.left, 0);
|
||||
mTmpTaskWindowBounds.winY = Utilities.mapRange(t,
|
||||
mSrcWindow.top, 0);
|
||||
|
||||
mTmpInsets.set(mInsets);
|
||||
Utilities.scaleRect(mTmpInsets, (1f - t));
|
||||
mTmpTaskWindowBounds.winCrop.set(mWindow);
|
||||
Utilities.insetRect(mTmpTaskWindowBounds.winCrop, mTmpInsets);
|
||||
|
||||
return mTmpTaskWindowBounds;
|
||||
}
|
||||
}
|
|
@ -27,8 +27,7 @@ import android.content.ComponentName;
|
|||
import android.content.Context;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.graphics.Matrix;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.RectF;
|
||||
import android.os.UserHandle;
|
||||
import android.util.Log;
|
||||
import android.view.Surface;
|
||||
|
@ -36,17 +35,17 @@ import android.view.View;
|
|||
|
||||
import com.android.launcher3.BaseDraggingActivity;
|
||||
import com.android.launcher3.ItemInfo;
|
||||
import com.android.launcher3.Utilities;
|
||||
import com.android.launcher3.compat.LauncherAppsCompat;
|
||||
import com.android.launcher3.compat.UserManagerCompat;
|
||||
import com.android.launcher3.util.ComponentKey;
|
||||
import com.android.quickstep.RecentsAnimationInterpolator.TaskWindowBounds;
|
||||
import com.android.quickstep.util.ClipAnimationHelper;
|
||||
import com.android.quickstep.util.MultiValueUpdateListener;
|
||||
import com.android.quickstep.util.RemoteAnimationProvider;
|
||||
import com.android.quickstep.util.RemoteAnimationTargetSet;
|
||||
import com.android.quickstep.views.RecentsView;
|
||||
import com.android.quickstep.views.TaskView;
|
||||
import com.android.systemui.shared.recents.model.Task;
|
||||
import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
|
||||
import com.android.systemui.shared.system.TransactionCompat;
|
||||
|
||||
/**
|
||||
* Contains helpful methods for retrieving data from {@link Task}s.
|
||||
|
@ -136,74 +135,64 @@ public class TaskUtils {
|
|||
return taskView;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return Animator that controls the window of the opening targets for the recents launch
|
||||
* animation.
|
||||
*/
|
||||
public static ValueAnimator getRecentsWindowAnimator(TaskView v, boolean skipViewChanges,
|
||||
RemoteAnimationTargetCompat[] targets) {
|
||||
final RecentsAnimationInterpolator recentsInterpolator = v.getRecentsInterpolator();
|
||||
|
||||
Rect crop = new Rect();
|
||||
Matrix matrix = new Matrix();
|
||||
|
||||
ValueAnimator appAnimator = ValueAnimator.ofFloat(0, 1);
|
||||
RemoteAnimationTargetCompat[] targets, final ClipAnimationHelper inOutHelper) {
|
||||
final ValueAnimator appAnimator = ValueAnimator.ofFloat(0, 1);
|
||||
appAnimator.setInterpolator(TOUCH_RESPONSE_INTERPOLATOR);
|
||||
appAnimator.addUpdateListener(new MultiValueUpdateListener() {
|
||||
|
||||
// Defer fading out the view until after the app window gets faded in
|
||||
FloatProp mViewAlpha = new FloatProp(1f, 0f, 75, 75, LINEAR);
|
||||
FloatProp mTaskAlpha = new FloatProp(0f, 1f, 0, 75, LINEAR);
|
||||
final FloatProp mViewAlpha = new FloatProp(1f, 0f, 75, 75, LINEAR);
|
||||
final FloatProp mTaskAlpha = new FloatProp(0f, 1f, 0, 75, LINEAR);
|
||||
|
||||
boolean isFirstFrame = true;
|
||||
final RemoteAnimationTargetSet mTargetSet;
|
||||
|
||||
final RectF mThumbnailRect;
|
||||
private Surface mSurface;
|
||||
private long mFrameNumber;
|
||||
|
||||
{
|
||||
mTargetSet = new RemoteAnimationTargetSet(targets, MODE_OPENING);
|
||||
inOutHelper.setTaskTransformCallback((t, app) -> {
|
||||
t.setAlpha(app.leash, mTaskAlpha.value);
|
||||
|
||||
if (!skipViewChanges) {
|
||||
t.deferTransactionUntil(app.leash, mSurface, mFrameNumber);
|
||||
}
|
||||
});
|
||||
|
||||
inOutHelper.prepareAnimation(true /* isOpening */);
|
||||
inOutHelper.fromTaskThumbnailView(v.getThumbnail(), (RecentsView) v.getParent(),
|
||||
mTargetSet.apps.length == 0 ? null : mTargetSet.apps[0]);
|
||||
|
||||
mThumbnailRect = new RectF(inOutHelper.getTargetRect());
|
||||
mThumbnailRect.offset(-v.getTranslationX(), -v.getTranslationY());
|
||||
Utilities.scaleRectFAboutCenter(mThumbnailRect, 1 / v.getScaleX());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUpdate(float percent) {
|
||||
final Surface surface = getSurface(v);
|
||||
final long frameNumber = surface != null ? getNextFrameNumber(surface) : -1;
|
||||
if (frameNumber == -1) {
|
||||
mSurface = getSurface(v);
|
||||
mFrameNumber = mSurface != null ? getNextFrameNumber(mSurface) : -1;
|
||||
if (mFrameNumber == -1) {
|
||||
// Booo, not cool! Our surface got destroyed, so no reason to animate anything.
|
||||
Log.w(TAG, "Failed to animate, surface got destroyed.");
|
||||
return;
|
||||
}
|
||||
TaskWindowBounds tw = recentsInterpolator.interpolate(percent);
|
||||
|
||||
RectF taskBounds = inOutHelper.applyTransform(mTargetSet, 1 - percent);
|
||||
if (!skipViewChanges) {
|
||||
v.setScaleX(tw.taskScale);
|
||||
v.setScaleY(tw.taskScale);
|
||||
v.setTranslationX(tw.taskX);
|
||||
v.setTranslationY(tw.taskY);
|
||||
float scale = taskBounds.width() / mThumbnailRect.width();
|
||||
v.setScaleX(scale);
|
||||
v.setScaleY(scale);
|
||||
v.setTranslationX(taskBounds.centerX() - mThumbnailRect.centerX());
|
||||
v.setTranslationY(taskBounds.centerY() - mThumbnailRect.centerY());
|
||||
v.setAlpha(mViewAlpha.value);
|
||||
}
|
||||
|
||||
matrix.setScale(tw.winScale, tw.winScale);
|
||||
matrix.postTranslate(tw.winX, tw.winY);
|
||||
crop.set(tw.winCrop);
|
||||
|
||||
TransactionCompat t = new TransactionCompat();
|
||||
if (isFirstFrame) {
|
||||
RemoteAnimationProvider.prepareTargetsForFirstFrame(targets, t, MODE_OPENING);
|
||||
isFirstFrame = false;
|
||||
}
|
||||
for (RemoteAnimationTargetCompat target : targets) {
|
||||
if (target.mode == RemoteAnimationTargetCompat.MODE_OPENING) {
|
||||
t.setAlpha(target.leash, mTaskAlpha.value);
|
||||
|
||||
// TODO: This isn't correct at the beginning of the animation, but better
|
||||
// than nothing.
|
||||
matrix.postTranslate(target.position.x, target.position.y);
|
||||
t.setMatrix(target.leash, matrix);
|
||||
t.setWindowCrop(target.leash, crop);
|
||||
|
||||
if (!skipViewChanges) {
|
||||
t.deferTransactionUntil(target.leash, surface, frameNumber);
|
||||
}
|
||||
}
|
||||
}
|
||||
t.apply();
|
||||
|
||||
matrix.reset();
|
||||
}
|
||||
});
|
||||
return appAnimator;
|
||||
|
|
|
@ -20,13 +20,16 @@ import static com.android.launcher3.anim.Interpolators.SCROLL;
|
|||
import static com.android.systemui.shared.system.RemoteAnimationTargetCompat.MODE_CLOSING;
|
||||
import static com.android.systemui.shared.system.RemoteAnimationTargetCompat.MODE_OPENING;
|
||||
|
||||
import android.annotation.TargetApi;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Matrix;
|
||||
import android.graphics.Matrix.ScaleToFit;
|
||||
import android.graphics.PointF;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.RectF;
|
||||
import android.os.Build;
|
||||
import android.os.RemoteException;
|
||||
import android.support.annotation.Nullable;
|
||||
|
||||
import com.android.launcher3.BaseDraggingActivity;
|
||||
import com.android.launcher3.DeviceProfile;
|
||||
|
@ -42,9 +45,12 @@ import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
|
|||
import com.android.systemui.shared.system.TransactionCompat;
|
||||
import com.android.systemui.shared.system.WindowManagerWrapper;
|
||||
|
||||
import java.util.function.BiConsumer;
|
||||
|
||||
/**
|
||||
* Utility class to handle window clip animation
|
||||
*/
|
||||
@TargetApi(Build.VERSION_CODES.P)
|
||||
public class ClipAnimationHelper {
|
||||
|
||||
// The bounds of the source app in device coordinates
|
||||
|
@ -78,13 +84,21 @@ public class ClipAnimationHelper {
|
|||
// Wether or not applyTransform has been called yet since prepareAnimation()
|
||||
private boolean mIsFirstFrame = true;
|
||||
|
||||
public void updateSource(Rect homeStackBounds, RemoteAnimationTargetCompat target) {
|
||||
mHomeStackBounds.set(homeStackBounds);
|
||||
private BiConsumer<TransactionCompat, RemoteAnimationTargetCompat> mTaskTransformCallback =
|
||||
(t, a) -> { };
|
||||
|
||||
private void updateSourceStack(RemoteAnimationTargetCompat target) {
|
||||
mSourceInsets.set(target.contentInsets);
|
||||
mSourceStackBounds.set(target.sourceContainerBounds);
|
||||
|
||||
// TODO: Should sourceContainerBounds already have this offset?
|
||||
mSourceStackBounds.offsetTo(target.position.x, target.position.y);
|
||||
|
||||
}
|
||||
|
||||
public void updateSource(Rect homeStackBounds, RemoteAnimationTargetCompat target) {
|
||||
mHomeStackBounds.set(homeStackBounds);
|
||||
updateSourceStack(target);
|
||||
}
|
||||
|
||||
public void updateTargetRect(Rect targetRect) {
|
||||
|
@ -116,7 +130,7 @@ public class ClipAnimationHelper {
|
|||
mBoostModeTargetLayers = isOpening ? MODE_OPENING : MODE_CLOSING;
|
||||
}
|
||||
|
||||
public void applyTransform(RemoteAnimationTargetSet targetSet, float progress) {
|
||||
public RectF applyTransform(RemoteAnimationTargetSet targetSet, float progress) {
|
||||
RectF currentRect;
|
||||
mTmpRectF.set(mTargetRect);
|
||||
Utilities.scaleRectFAboutCenter(mTmpRectF, mTargetScale);
|
||||
|
@ -153,8 +167,16 @@ public class ClipAnimationHelper {
|
|||
|| app.activityType == RemoteAnimationTargetCompat.ACTIVITY_TYPE_HOME) {
|
||||
transaction.setAlpha(app.leash, 1 - progress);
|
||||
}
|
||||
|
||||
mTaskTransformCallback.accept(transaction, app);
|
||||
}
|
||||
transaction.apply();
|
||||
return currentRect;
|
||||
}
|
||||
|
||||
public void setTaskTransformCallback
|
||||
(BiConsumer<TransactionCompat, RemoteAnimationTargetCompat> callback) {
|
||||
mTaskTransformCallback = callback;
|
||||
}
|
||||
|
||||
public void offsetTarget(float scale, float offsetX, float offsetY) {
|
||||
|
@ -165,6 +187,11 @@ public class ClipAnimationHelper {
|
|||
}
|
||||
|
||||
public void fromTaskThumbnailView(TaskThumbnailView ttv, RecentsView rv) {
|
||||
fromTaskThumbnailView(ttv, rv, null);
|
||||
}
|
||||
|
||||
public void fromTaskThumbnailView(TaskThumbnailView ttv, RecentsView rv,
|
||||
@Nullable RemoteAnimationTargetCompat target) {
|
||||
BaseDraggingActivity activity = BaseDraggingActivity.fromContext(ttv.getContext());
|
||||
BaseDragLayer dl = activity.getDragLayer();
|
||||
|
||||
|
@ -173,7 +200,9 @@ public class ClipAnimationHelper {
|
|||
mHomeStackBounds.set(0, 0, dl.getWidth(), dl.getHeight());
|
||||
mHomeStackBounds.offset(pos[0], pos[1]);
|
||||
|
||||
if (rv.shouldUseMultiWindowTaskSizeStrategy()) {
|
||||
if (target != null) {
|
||||
updateSourceStack(target);
|
||||
} else if (rv.shouldUseMultiWindowTaskSizeStrategy()) {
|
||||
updateStackBoundsToMultiWindowTaskSize(activity);
|
||||
} else {
|
||||
mSourceStackBounds.set(mHomeStackBounds);
|
||||
|
@ -226,7 +255,6 @@ public class ClipAnimationHelper {
|
|||
insets.top + fullDp.availableHeightPx - taskHeight);
|
||||
}
|
||||
|
||||
|
||||
public void drawForProgress(TaskThumbnailView ttv, Canvas canvas, float progress) {
|
||||
RectF currentRect = mRectFEvaluator.evaluate(progress, mSourceRect, mTargetRect);
|
||||
canvas.translate(mSourceStackBounds.left - mHomeStackBounds.left,
|
||||
|
@ -244,4 +272,12 @@ public class ClipAnimationHelper {
|
|||
ttv.getMeasuredHeight() + mSourceWindowClipInsets.bottom * insetProgress,
|
||||
ttv.getCornerRadius() * progress);
|
||||
}
|
||||
|
||||
public RectF getTargetRect() {
|
||||
return mTargetRect;
|
||||
}
|
||||
|
||||
public RectF getSourceRect() {
|
||||
return mSourceRect;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -87,6 +87,10 @@ public class TaskViewDrawable extends Drawable {
|
|||
canvas.restore();
|
||||
}
|
||||
|
||||
public ClipAnimationHelper getClipAnimationHelper() {
|
||||
return mClipAnimationHelper;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAlpha(int i) { }
|
||||
|
||||
|
|
|
@ -36,6 +36,7 @@ import com.android.launcher3.DeviceProfile;
|
|||
import com.android.launcher3.Launcher;
|
||||
import com.android.launcher3.LauncherState;
|
||||
import com.android.quickstep.OverviewInteractionState;
|
||||
import com.android.quickstep.util.ClipAnimationHelper;
|
||||
import com.android.quickstep.util.LayoutUtils;
|
||||
|
||||
/**
|
||||
|
@ -116,8 +117,9 @@ public class LauncherRecentsView extends RecentsView<Launcher> {
|
|||
* Animates adjacent tasks and translate hotseat off screen as well.
|
||||
*/
|
||||
@Override
|
||||
public AnimatorSet createAdjacentPageAnimForTaskLaunch(TaskView tv) {
|
||||
AnimatorSet anim = super.createAdjacentPageAnimForTaskLaunch(tv);
|
||||
public AnimatorSet createAdjacentPageAnimForTaskLaunch(TaskView tv,
|
||||
ClipAnimationHelper helper) {
|
||||
AnimatorSet anim = super.createAdjacentPageAnimForTaskLaunch(tv, helper);
|
||||
|
||||
if (!OverviewInteractionState.getInstance(mActivity).isSwipeUpGestureEnabled()) {
|
||||
// Hotseat doesn't move when opening recents with the button,
|
||||
|
|
|
@ -65,9 +65,9 @@ import com.android.launcher3.util.PendingAnimation;
|
|||
import com.android.launcher3.util.Themes;
|
||||
import com.android.quickstep.OverviewCallbacks;
|
||||
import com.android.quickstep.QuickScrubController;
|
||||
import com.android.quickstep.RecentsAnimationInterpolator.TaskWindowBounds;
|
||||
import com.android.quickstep.RecentsModel;
|
||||
import com.android.quickstep.TaskUtils;
|
||||
import com.android.quickstep.util.ClipAnimationHelper;
|
||||
import com.android.quickstep.util.TaskViewDrawable;
|
||||
import com.android.systemui.shared.recents.model.RecentsTaskLoadPlan;
|
||||
import com.android.systemui.shared.recents.model.RecentsTaskLoader;
|
||||
|
@ -1095,17 +1095,18 @@ public abstract class RecentsView<T extends BaseActivity> extends PagedView impl
|
|||
* If launching one of the adjacent tasks, parallax the center task and other adjacent task
|
||||
* to the right.
|
||||
*/
|
||||
public AnimatorSet createAdjacentPageAnimForTaskLaunch(TaskView tv) {
|
||||
public AnimatorSet createAdjacentPageAnimForTaskLaunch(
|
||||
TaskView tv, ClipAnimationHelper clipAnimationHelper) {
|
||||
AnimatorSet anim = new AnimatorSet();
|
||||
|
||||
int taskIndex = indexOfChild(tv);
|
||||
int centerTaskIndex = getCurrentPage();
|
||||
boolean launchingCenterTask = taskIndex == centerTaskIndex;
|
||||
|
||||
TaskWindowBounds endInterpolation = tv.getRecentsInterpolator().interpolate(1);
|
||||
float toScale = endInterpolation.taskScale;
|
||||
float toTranslationY = endInterpolation.taskY;
|
||||
|
||||
float toScale = clipAnimationHelper.getSourceRect().width()
|
||||
/ clipAnimationHelper.getTargetRect().width();
|
||||
float toTranslationY = clipAnimationHelper.getSourceRect().centerY()
|
||||
- clipAnimationHelper.getTargetRect().centerY();
|
||||
if (launchingCenterTask) {
|
||||
TaskView centerTask = getPageAt(centerTaskIndex);
|
||||
if (taskIndex - 1 >= 0) {
|
||||
|
@ -1152,11 +1153,10 @@ public abstract class RecentsView<T extends BaseActivity> extends PagedView impl
|
|||
if (FeatureFlags.IS_DOGFOOD_BUILD && mPendingAnimation != null) {
|
||||
throw new IllegalStateException("Another pending animation is still running");
|
||||
}
|
||||
AnimatorSet anim = createAdjacentPageAnimForTaskLaunch(tv);
|
||||
|
||||
int count = getChildCount();
|
||||
if (count == 0) {
|
||||
return new PendingAnimation(anim);
|
||||
return new PendingAnimation(new AnimatorSet());
|
||||
}
|
||||
|
||||
tv.setVisibility(INVISIBLE);
|
||||
|
@ -1167,6 +1167,8 @@ public abstract class RecentsView<T extends BaseActivity> extends PagedView impl
|
|||
ObjectAnimator.ofFloat(drawable, TaskViewDrawable.PROGRESS, 1, 0);
|
||||
drawableAnim.setInterpolator(LINEAR);
|
||||
|
||||
AnimatorSet anim = createAdjacentPageAnimForTaskLaunch(tv,
|
||||
drawable.getClipAnimationHelper());
|
||||
anim.play(drawableAnim);
|
||||
anim.setDuration(duration);
|
||||
|
||||
|
|
|
@ -26,7 +26,6 @@ import android.app.ActivityOptions;
|
|||
import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
import android.graphics.Outline;
|
||||
import android.graphics.Rect;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.util.AttributeSet;
|
||||
|
@ -39,11 +38,9 @@ import android.widget.ImageView;
|
|||
|
||||
import com.android.launcher3.BaseActivity;
|
||||
import com.android.launcher3.BaseDraggingActivity;
|
||||
import com.android.launcher3.DeviceProfile;
|
||||
import com.android.launcher3.R;
|
||||
import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Direction;
|
||||
import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Touch;
|
||||
import com.android.quickstep.RecentsAnimationInterpolator;
|
||||
import com.android.quickstep.TaskSystemShortcut;
|
||||
import com.android.quickstep.TaskUtils;
|
||||
import com.android.quickstep.views.RecentsView.PageCallbacks;
|
||||
|
@ -231,6 +228,13 @@ public class TaskView extends FrameLayout implements TaskCallbacks, PageCallback
|
|||
setScaleY(mCurveScale);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
|
||||
super.onLayout(changed, left, top, right, bottom);
|
||||
setPivotX((right - left) * 0.5f);
|
||||
setPivotY(mSnapshotView.getTop() + mSnapshotView.getHeight() * 0.5f);
|
||||
}
|
||||
|
||||
public float getCurveScaleForInterpolation(float linearInterpolation) {
|
||||
float curveInterpolation = CURVE_INTERPOLATOR.getInterpolation(linearInterpolation);
|
||||
return getCurveScaleForCurveInterpolation(curveInterpolation);
|
||||
|
@ -250,23 +254,6 @@ public class TaskView extends FrameLayout implements TaskCallbacks, PageCallback
|
|||
return false;
|
||||
}
|
||||
|
||||
public RecentsAnimationInterpolator getRecentsInterpolator() {
|
||||
Rect taskViewBounds = new Rect();
|
||||
BaseDraggingActivity activity = BaseDraggingActivity.fromContext(getContext());
|
||||
DeviceProfile dp = activity.getDeviceProfile();
|
||||
activity.getDragLayer().getDescendantRectRelativeToSelf(this, taskViewBounds);
|
||||
|
||||
// TODO: Use the actual target insets instead of the current thumbnail insets in case the
|
||||
// device state has changed
|
||||
return new RecentsAnimationInterpolator(
|
||||
new Rect(0, 0, dp.widthPx, dp.heightPx),
|
||||
getThumbnail().getInsets(),
|
||||
taskViewBounds,
|
||||
new Rect(0, getThumbnail().getTop(), 0, 0),
|
||||
getScaleX(),
|
||||
getTranslationX());
|
||||
}
|
||||
|
||||
private static final class TaskOutlineProvider extends ViewOutlineProvider {
|
||||
|
||||
private final int mMarginTop;
|
||||
|
|
Loading…
Reference in New Issue