diff --git a/quickstep/res/values/dimens.xml b/quickstep/res/values/dimens.xml index ffd83b1ac5..b39a8d3f09 100644 --- a/quickstep/res/values/dimens.xml +++ b/quickstep/res/values/dimens.xml @@ -64,7 +64,7 @@ 0.5dp - 50dp + 0.97 115dp 16sp diff --git a/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java b/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java index 3aa758fec2..6912f94fb4 100644 --- a/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java +++ b/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java @@ -23,11 +23,14 @@ import static com.android.launcher3.BaseActivity.INVISIBLE_ALL; import static com.android.launcher3.BaseActivity.INVISIBLE_BY_APP_TRANSITIONS; import static com.android.launcher3.BaseActivity.INVISIBLE_BY_PENDING_FLAGS; import static com.android.launcher3.BaseActivity.PENDING_INVISIBLE_BY_WALLPAPER_ANIMATION; +import static com.android.launcher3.LauncherAnimUtils.SCALE_PROPERTY; +import static com.android.launcher3.LauncherAnimUtils.VIEW_BACKGROUND_COLOR; import static com.android.launcher3.LauncherState.ALL_APPS; import static com.android.launcher3.LauncherState.BACKGROUND_APP; import static com.android.launcher3.LauncherState.OVERVIEW; import static com.android.launcher3.Utilities.postAsyncCallback; import static com.android.launcher3.anim.Interpolators.AGGRESSIVE_EASE; +import static com.android.launcher3.anim.Interpolators.DEACCEL_1_5; import static com.android.launcher3.anim.Interpolators.DEACCEL_1_7; import static com.android.launcher3.anim.Interpolators.EXAGGERATED_EASE; import static com.android.launcher3.anim.Interpolators.LINEAR; @@ -50,10 +53,12 @@ import android.animation.ValueAnimator; import android.content.Context; import android.content.pm.PackageManager; import android.content.res.Resources; +import android.graphics.Color; import android.graphics.Matrix; import android.graphics.Point; import android.graphics.Rect; import android.graphics.RectF; +import android.graphics.drawable.ColorDrawable; import android.graphics.drawable.Drawable; import android.os.CancellationSignal; import android.os.Handler; @@ -67,6 +72,7 @@ import android.view.animation.PathInterpolator; import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import androidx.core.graphics.ColorUtils; import com.android.launcher3.DeviceProfile.OnDeviceProfileChangeListener; import com.android.launcher3.anim.AnimationSuccessListener; @@ -75,10 +81,11 @@ import com.android.launcher3.icons.FastBitmapDrawable; import com.android.launcher3.shortcuts.DeepShortcutView; import com.android.launcher3.statehandlers.DepthController; import com.android.launcher3.util.ActivityOptionsWrapper; -import com.android.launcher3.util.MultiValueAlpha; import com.android.launcher3.util.MultiValueAlpha.AlphaProperty; import com.android.launcher3.util.RunnableList; +import com.android.launcher3.util.Themes; import com.android.launcher3.views.FloatingIconView; +import com.android.launcher3.views.ScrimView; import com.android.launcher3.widget.LauncherAppWidgetHostView; import com.android.quickstep.RemoteAnimationTargets; import com.android.quickstep.SystemUiProxy; @@ -160,7 +167,8 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener private static final int CLOSING_TRANSITION_DURATION_MS = 250; public static final int CONTENT_ALPHA_DURATION = 217; - protected static final int CONTENT_TRANSLATION_DURATION = 350; + protected static final int CONTENT_SCALE_DURATION = 350; + protected static final int CONTENT_SCRIM_DURATION = 350; private static final int MAX_NUM_TASKS = 5; @@ -173,9 +181,8 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener private final AlphaProperty mDragLayerAlpha; final Handler mHandler; - private final boolean mIsRtl; - private final float mContentTransY; + private final float mContentScale; private final float mClosingWindowTransY; private final float mMaxShadowRadius; @@ -212,11 +219,10 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener mDragLayer = mLauncher.getDragLayer(); mDragLayerAlpha = mDragLayer.getAlphaProperty(ALPHA_INDEX_TRANSITIONS); mHandler = new Handler(Looper.getMainLooper()); - mIsRtl = Utilities.isRtl(mLauncher.getResources()); mDeviceProfile = mLauncher.getDeviceProfile(); Resources res = mLauncher.getResources(); - mContentTransY = res.getDimensionPixelSize(R.dimen.content_trans_y); + mContentScale = res.getFloat(R.dimen.content_scale); mClosingWindowTransY = res.getDimensionPixelSize(R.dimen.closing_window_trans_y); mMaxShadowRadius = res.getDimensionPixelSize(R.dimen.max_shadow_radius); @@ -335,8 +341,7 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener windowTargetBounds, areAllTargetsTranslucent(appTargets), rotationChange)); if (launcherClosing) { Pair launcherContentAnimator = - getLauncherContentAnimator(true /* isAppOpening */, - new float[] {0, -mContentTransY}); + getLauncherContentAnimator(true /* isAppOpening */); anim.play(launcherContentAnimator.first); anim.addListener(new AnimatorListenerAdapter() { @Override @@ -436,10 +441,8 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener * * @param isAppOpening True when this is called when an app is opening. * False when this is called when an app is closing. - * @param trans Array that contains the start and end translation values for the content. */ - private Pair getLauncherContentAnimator(boolean isAppOpening, - float[] trans) { + private Pair getLauncherContentAnimator(boolean isAppOpening) { AnimatorSet launcherAnimator = new AnimatorSet(); Runnable endListener; @@ -447,13 +450,17 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener ? new float[] {1, 0} : new float[] {0, 1}; + float[] scales = isAppOpening + ? new float[] {1, mContentScale} + : new float[] {mContentScale, 1}; + if (mLauncher.isInState(ALL_APPS)) { // All Apps in portrait mode is full screen, so we only animate AllAppsContainerView. final View appsView = mLauncher.getAppsView(); final float startAlpha = appsView.getAlpha(); - final float startY = appsView.getTranslationY(); + final float startScale = SCALE_PROPERTY.get(appsView); appsView.setAlpha(alphas[0]); - appsView.setTranslationY(trans[0]); + SCALE_PROPERTY.set(appsView, scales[0]); ObjectAnimator alpha = ObjectAnimator.ofFloat(appsView, View.ALPHA, alphas); alpha.setDuration(CONTENT_ALPHA_DURATION); @@ -465,30 +472,22 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener appsView.setLayerType(View.LAYER_TYPE_NONE, null); } }); - ObjectAnimator transY = ObjectAnimator.ofFloat(appsView, View.TRANSLATION_Y, trans); - transY.setInterpolator(AGGRESSIVE_EASE); - transY.setDuration(CONTENT_TRANSLATION_DURATION); + ObjectAnimator scale = ObjectAnimator.ofFloat(appsView, SCALE_PROPERTY, scales); + scale.setInterpolator(AGGRESSIVE_EASE); + scale.setDuration(CONTENT_SCALE_DURATION); launcherAnimator.play(alpha); - launcherAnimator.play(transY); + launcherAnimator.play(scale); endListener = () -> { appsView.setAlpha(startAlpha); - appsView.setTranslationY(startY); + SCALE_PROPERTY.set(appsView, startScale); appsView.setLayerType(View.LAYER_TYPE_NONE, null); }; } else if (mLauncher.isInState(OVERVIEW)) { - endListener = composeViewContentAnimator(launcherAnimator, alphas, trans); + endListener = composeViewContentAnimator(launcherAnimator, alphas, scales); } else { - mDragLayerAlpha.setValue(alphas[0]); - ObjectAnimator alpha = - ObjectAnimator.ofFloat(mDragLayerAlpha, MultiValueAlpha.VALUE, alphas); - alpha.setDuration(CONTENT_ALPHA_DURATION); - alpha.setInterpolator(LINEAR); - launcherAnimator.play(alpha); - List viewsToAnimate = new ArrayList<>(); - Workspace workspace = mLauncher.getWorkspace(); workspace.forEachVisiblePage( view -> viewsToAnimate.add(((CellLayout) view).getShortcutsAndWidgets())); @@ -499,18 +498,38 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener viewsToAnimate.forEach(view -> { view.setLayerType(View.LAYER_TYPE_HARDWARE, null); - launcherAnimator.play(ObjectAnimator.ofFloat(view, View.TRANSLATION_Y, trans)); + + ObjectAnimator scaleAnim = ObjectAnimator.ofFloat(view, SCALE_PROPERTY, scales) + .setDuration(CONTENT_SCALE_DURATION); + scaleAnim.setInterpolator(DEACCEL_1_5); + launcherAnimator.play(scaleAnim); }); + int scrimColor = Themes.getAttrColor(mLauncher, R.attr.overviewScrimColor); + int scrimColorTrans = ColorUtils.setAlphaComponent(scrimColor, 0); + int[] colors = isAppOpening + ? new int[] {scrimColorTrans, scrimColor} + : new int[] {scrimColor, scrimColorTrans}; + ScrimView scrimView = mLauncher.getScrimView(); + if (scrimView.getBackground() instanceof ColorDrawable) { + scrimView.setBackgroundColor(colors[0]); + + ObjectAnimator scrim = ObjectAnimator.ofArgb(scrimView, VIEW_BACKGROUND_COLOR, + colors); + scrim.setDuration(CONTENT_SCRIM_DURATION); + scrim.setInterpolator(DEACCEL_1_5); + launcherAnimator.play(scrim); + } + // Pause page indicator animations as they lead to layer trashing. mLauncher.getWorkspace().getPageIndicator().pauseAnimations(); endListener = () -> { viewsToAnimate.forEach(view -> { - view.setTranslationY(0); + SCALE_PROPERTY.set(view, 1f); view.setLayerType(View.LAYER_TYPE_NONE, null); }); - mDragLayerAlpha.setValue(1f); + scrimView.setBackgroundColor(Color.TRANSPARENT); mLauncher.getWorkspace().getPageIndicator().skipAnimationsToEnd(); }; } @@ -522,11 +541,11 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener * * @param anim the animator set to add to * @param alphas the alphas to animate to over time - * @param trans the translation Y values to animator to over time + * @param scales the scale values to animator to over time * @return listener to run when the animation ends */ protected Runnable composeViewContentAnimator(@NonNull AnimatorSet anim, - float[] alphas, float[] trans) { + float[] alphas, float[] scales) { RecentsView overview = mLauncher.getOverviewPanel(); ObjectAnimator alpha = ObjectAnimator.ofFloat(overview, RecentsView.CONTENT_ALPHA, alphas); @@ -535,14 +554,14 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener anim.play(alpha); overview.setFreezeViewVisibility(true); - ObjectAnimator transY = ObjectAnimator.ofFloat(overview, View.TRANSLATION_Y, trans); - transY.setInterpolator(AGGRESSIVE_EASE); - transY.setDuration(CONTENT_TRANSLATION_DURATION); - anim.play(transY); + ObjectAnimator scaleAnim = ObjectAnimator.ofFloat(overview, SCALE_PROPERTY, scales); + scaleAnim.setInterpolator(AGGRESSIVE_EASE); + scaleAnim.setDuration(CONTENT_SCALE_DURATION); + anim.play(scaleAnim); return () -> { overview.setFreezeViewVisibility(false); - overview.setTranslationY(0); + SCALE_PROPERTY.set(overview, 1f); mLauncher.getStateManager().reapplyState(); }; } @@ -1223,8 +1242,7 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener if (mLauncher.isInState(LauncherState.ALL_APPS)) { Pair contentAnimator = - getLauncherContentAnimator(false /* isAppOpening */, - new float[] {-mContentTransY, 0}); + getLauncherContentAnimator(false /* isAppOpening */); contentAnimator.first.setStartDelay(LAUNCHER_RESUME_START_DELAY); anim.play(contentAnimator.first); anim.addListener(new AnimatorListenerAdapter() {