Polish app => recents animation (3/N)
This CL takes the current scale down animation and updates its interpolators and durations to match the UX spec. In addition, we move the core logic to a helper method as the whole remote animation will have other animations as well in the future. Bug: 132112131 Test: Manual Change-Id: I68b1d623b1b2c980dc34e41bbb5460cc021b5887
This commit is contained in:
parent
1b4b960ff1
commit
e590014834
|
@ -23,7 +23,6 @@ import static com.android.systemui.shared.system.RemoteAnimationTargetCompat.MOD
|
|||
import android.animation.AnimatorSet;
|
||||
import android.animation.ValueAnimator;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
|
||||
import com.android.launcher3.BaseDraggingActivity;
|
||||
import com.android.quickstep.util.RemoteAnimationProvider;
|
||||
|
@ -119,7 +118,7 @@ final class AppToOverviewAnimationProvider<T extends BaseDraggingActivity> imple
|
|||
return anim;
|
||||
}
|
||||
|
||||
mRecentsView.playAppScaleDownAnim(anim, closingAppTarget, recentsTarget);
|
||||
mRecentsView.playRemoteAppToRecentsAnimation(anim, closingAppTarget, recentsTarget);
|
||||
|
||||
return anim;
|
||||
}
|
||||
|
|
|
@ -20,7 +20,6 @@ import static android.content.res.Configuration.ORIENTATION_LANDSCAPE;
|
|||
import static androidx.recyclerview.widget.LinearLayoutManager.VERTICAL;
|
||||
|
||||
import static com.android.launcher3.anim.Interpolators.ACCEL_2;
|
||||
import static com.android.launcher3.anim.Interpolators.ACCEL_DEACCEL;
|
||||
import static com.android.quickstep.TaskAdapter.CHANGE_EVENT_TYPE_EMPTY_TO_CONTENT;
|
||||
import static com.android.quickstep.TaskAdapter.ITEM_TYPE_CLEAR_ALL;
|
||||
import static com.android.quickstep.TaskAdapter.ITEM_TYPE_TASK;
|
||||
|
@ -45,6 +44,7 @@ import android.util.FloatProperty;
|
|||
import android.view.View;
|
||||
import android.view.ViewDebug;
|
||||
import android.view.ViewTreeObserver;
|
||||
import android.view.animation.PathInterpolator;
|
||||
import android.widget.FrameLayout;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
@ -111,10 +111,15 @@ public final class IconRecentsView extends FrameLayout implements Insettable {
|
|||
private static final float ITEM_ANIMATE_OUT_TRANSLATION_X_RATIO = .25f;
|
||||
private static final long CLEAR_ALL_FADE_DELAY = 120;
|
||||
|
||||
private static final long APP_TO_THUMBNAIL_FADE_DURATION = 50;
|
||||
private static final long APP_SCALE_DOWN_DURATION = 400;
|
||||
private static final long REMOTE_TO_RECENTS_APP_SCALE_DOWN_DURATION = 300;
|
||||
|
||||
public static final long REMOTE_APP_TO_OVERVIEW_DURATION = APP_SCALE_DOWN_DURATION;
|
||||
private static final PathInterpolator FAST_OUT_SLOW_IN_1 =
|
||||
new PathInterpolator(.4f, 0f, 0f, 1f);
|
||||
private static final PathInterpolator FAST_OUT_SLOW_IN_2 =
|
||||
new PathInterpolator(.5f, 0f, 0f, 1f);
|
||||
|
||||
public static final long REMOTE_APP_TO_OVERVIEW_DURATION =
|
||||
REMOTE_TO_RECENTS_APP_SCALE_DOWN_DURATION;
|
||||
|
||||
/**
|
||||
* A ratio representing the view's relative placement within its padded space. For example, 0
|
||||
|
@ -397,7 +402,7 @@ public final class IconRecentsView extends FrameLayout implements Insettable {
|
|||
*
|
||||
* @return the thumbnail view if laid out
|
||||
*/
|
||||
public @Nullable View getBottomThumbnailView() {
|
||||
private @Nullable View getBottomThumbnailView() {
|
||||
ArrayList<TaskItemView> taskViews = getTaskViews();
|
||||
if (taskViews.isEmpty()) {
|
||||
return null;
|
||||
|
@ -580,18 +585,17 @@ public final class IconRecentsView extends FrameLayout implements Insettable {
|
|||
}
|
||||
|
||||
/**
|
||||
* Animate a closing app to scale down to the location of the thumbnail view in recents.
|
||||
* Play remote animation from app to recents. This should scale the currently closing app down
|
||||
* to the recents thumbnail.
|
||||
*
|
||||
* @param anim animator set
|
||||
* @param appTarget the app surface thats closing
|
||||
* @param recentsTarget the surface containing recents
|
||||
*/
|
||||
public void playAppScaleDownAnim(@NonNull AnimatorSet anim,
|
||||
public void playRemoteAppToRecentsAnimation(@NonNull AnimatorSet anim,
|
||||
@NonNull RemoteAnimationTargetCompat appTarget,
|
||||
@NonNull RemoteAnimationTargetCompat recentsTarget) {
|
||||
|
||||
View thumbnailView = getBottomThumbnailView();
|
||||
|
||||
if (thumbnailView == null) {
|
||||
// This can be null if there were previously 0 tasks and the recycler view has not had
|
||||
// enough time to take in the data change, bind a new view, and lay out the new view.
|
||||
|
@ -599,15 +603,28 @@ public final class IconRecentsView extends FrameLayout implements Insettable {
|
|||
anim.play(ValueAnimator.ofInt(0, 1).setDuration(REMOTE_APP_TO_OVERVIEW_DURATION));
|
||||
}
|
||||
|
||||
// TODO: Play other animations in app => recents
|
||||
playRemoteAppScaleDownAnim(anim, appTarget, recentsTarget, thumbnailView);
|
||||
}
|
||||
|
||||
/**
|
||||
* Play the scale down animation for the remote app to recents animation where the app surface
|
||||
* scales down to where the thumbnail is.
|
||||
*
|
||||
* @param anim animator set to play on
|
||||
* @param appTarget closing app target
|
||||
* @param recentsTarget opening recents target
|
||||
* @param thumbnailView thumbnail view to animate to
|
||||
*/
|
||||
private void playRemoteAppScaleDownAnim(@NonNull AnimatorSet anim,
|
||||
@NonNull RemoteAnimationTargetCompat appTarget,
|
||||
@NonNull RemoteAnimationTargetCompat recentsTarget,
|
||||
@NonNull View thumbnailView) {
|
||||
// Identify where the entering remote app should animate to.
|
||||
Rect endRect = new Rect();
|
||||
thumbnailView.getGlobalVisibleRect(endRect);
|
||||
|
||||
Rect appBounds = appTarget.sourceContainerBounds;
|
||||
|
||||
ValueAnimator valueAnimator = ValueAnimator.ofInt(0, 1);
|
||||
valueAnimator.setDuration(APP_SCALE_DOWN_DURATION);
|
||||
|
||||
SyncRtSurfaceTransactionApplierCompat surfaceApplier =
|
||||
new SyncRtSurfaceTransactionApplierCompat(thumbnailView);
|
||||
|
||||
|
@ -618,7 +635,9 @@ public final class IconRecentsView extends FrameLayout implements Insettable {
|
|||
params[0] = new SurfaceParams(recentsTarget.leash, 1f, null /* matrix */,
|
||||
null /* windowCrop */, getLayer(recentsTarget, boostedMode), 0 /* cornerRadius */);
|
||||
|
||||
valueAnimator.addUpdateListener(new MultiValueUpdateListener() {
|
||||
ValueAnimator remoteAppAnim = ValueAnimator.ofInt(0, 1);
|
||||
remoteAppAnim.setDuration(REMOTE_TO_RECENTS_APP_SCALE_DOWN_DURATION);
|
||||
remoteAppAnim.addUpdateListener(new MultiValueUpdateListener() {
|
||||
private final FloatProp mScaleX;
|
||||
private final FloatProp mScaleY;
|
||||
private final FloatProp mTranslationX;
|
||||
|
@ -628,30 +647,27 @@ public final class IconRecentsView extends FrameLayout implements Insettable {
|
|||
{
|
||||
// Scale down and move to view location.
|
||||
float endScaleX = ((float) endRect.width()) / appBounds.width();
|
||||
mScaleX = new FloatProp(1f, endScaleX, 0, APP_SCALE_DOWN_DURATION,
|
||||
ACCEL_DEACCEL);
|
||||
mScaleX = new FloatProp(1f, endScaleX, 0, REMOTE_TO_RECENTS_APP_SCALE_DOWN_DURATION,
|
||||
FAST_OUT_SLOW_IN_1);
|
||||
float endScaleY = ((float) endRect.height()) / appBounds.height();
|
||||
mScaleY = new FloatProp(1f, endScaleY, 0, APP_SCALE_DOWN_DURATION,
|
||||
ACCEL_DEACCEL);
|
||||
mScaleY = new FloatProp(1f, endScaleY, 0, REMOTE_TO_RECENTS_APP_SCALE_DOWN_DURATION,
|
||||
FAST_OUT_SLOW_IN_1);
|
||||
float endTranslationX = endRect.left -
|
||||
(appBounds.width() - thumbnailView.getWidth()) / 2.0f;
|
||||
mTranslationX = new FloatProp(0, endTranslationX, 0, APP_SCALE_DOWN_DURATION,
|
||||
ACCEL_DEACCEL);
|
||||
mTranslationX = new FloatProp(0, endTranslationX, 0,
|
||||
REMOTE_TO_RECENTS_APP_SCALE_DOWN_DURATION, FAST_OUT_SLOW_IN_1);
|
||||
float endTranslationY = endRect.top -
|
||||
(appBounds.height() - thumbnailView.getHeight()) / 2.0f;
|
||||
mTranslationY = new FloatProp(0, endTranslationY, 0, APP_SCALE_DOWN_DURATION,
|
||||
ACCEL_DEACCEL);
|
||||
|
||||
// Fade out quietly near the end to be replaced by the real view.
|
||||
mAlpha = new FloatProp(1.0f, 0,
|
||||
APP_SCALE_DOWN_DURATION - APP_TO_THUMBNAIL_FADE_DURATION,
|
||||
APP_TO_THUMBNAIL_FADE_DURATION, ACCEL_2);
|
||||
mTranslationY = new FloatProp(0, endTranslationY, 0,
|
||||
REMOTE_TO_RECENTS_APP_SCALE_DOWN_DURATION, FAST_OUT_SLOW_IN_2);
|
||||
mAlpha = new FloatProp(1.0f, 0, 0, REMOTE_TO_RECENTS_APP_SCALE_DOWN_DURATION,
|
||||
ACCEL_2);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUpdate(float percent) {
|
||||
Matrix m = new Matrix();
|
||||
m.setScale(mScaleX.value, mScaleY.value,
|
||||
m.preScale(mScaleX.value, mScaleY.value,
|
||||
appBounds.width() / 2.0f, appBounds.height() / 2.0f);
|
||||
m.postTranslate(mTranslationX.value, mTranslationY.value);
|
||||
|
||||
|
@ -661,11 +677,7 @@ public final class IconRecentsView extends FrameLayout implements Insettable {
|
|||
surfaceApplier.scheduleApply(params);
|
||||
}
|
||||
});
|
||||
anim.play(valueAnimator);
|
||||
}
|
||||
|
||||
public long getAppToOverviewAnimationDuration() {
|
||||
return APP_SCALE_DOWN_DURATION;
|
||||
anim.play(remoteAppAnim);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
Loading…
Reference in New Issue