Merge "Update animations for TM-QPR: OverviewSplitSelect > Confirmed transition" into tm-qpr-dev
This commit is contained in:
+4
-10
@@ -62,6 +62,7 @@ import com.android.launcher3.touch.AllAppsSwipeController;
|
||||
import com.android.launcher3.uioverrides.QuickstepLauncher;
|
||||
import com.android.launcher3.util.DisplayController;
|
||||
import com.android.quickstep.util.RecentsAtomicAnimationFactory;
|
||||
import com.android.quickstep.util.SplitAnimationTimings;
|
||||
import com.android.quickstep.views.RecentsView;
|
||||
|
||||
/**
|
||||
@@ -79,14 +80,6 @@ public class QuickstepAtomicAnimationFactory extends
|
||||
private static final int PER_PAGE_SCROLL_DURATION = 150;
|
||||
private static final int MAX_PAGE_SCROLL_DURATION = 750;
|
||||
|
||||
private static final int OVERVIEW_TO_SPLIT_ACTIONS_FADE_START = 0;
|
||||
private static final int OVERVIEW_TO_SPLIT_ACTIONS_FADE_END = 83;
|
||||
|
||||
private static final float OVERVIEW_TO_SPLIT_ACTIONS_FADE_START_OFFSET =
|
||||
(float) OVERVIEW_TO_SPLIT_ACTIONS_FADE_START / SplitScreenSelectState.ENTER_DURATION;
|
||||
private static final float OVERVIEW_TO_SPLIT_ACTIONS_FADE_END_OFFSET =
|
||||
(float) OVERVIEW_TO_SPLIT_ACTIONS_FADE_END / SplitScreenSelectState.ENTER_DURATION;
|
||||
|
||||
// Due to use of physics, duration may differ between devices so we need to calculate and
|
||||
// cache the value.
|
||||
private int mHintToNormalDuration = -1;
|
||||
@@ -197,9 +190,10 @@ public class QuickstepAtomicAnimationFactory extends
|
||||
} else if (fromState == NORMAL && toState == ALL_APPS) {
|
||||
AllAppsSwipeController.applyNormalToAllAppsAnimConfig(mActivity, config);
|
||||
} else if (fromState == OVERVIEW && toState == OVERVIEW_SPLIT_SELECT) {
|
||||
SplitAnimationTimings timings = SplitAnimationTimings.OVERVIEW_TO_SPLIT;
|
||||
config.setInterpolator(ANIM_OVERVIEW_ACTIONS_FADE, clampToProgress(LINEAR,
|
||||
OVERVIEW_TO_SPLIT_ACTIONS_FADE_START_OFFSET,
|
||||
OVERVIEW_TO_SPLIT_ACTIONS_FADE_END_OFFSET));
|
||||
timings.getActionsFadeStartOffset(),
|
||||
timings.getActionsFadeEndOffset()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@ package com.android.launcher3.uioverrides.states;
|
||||
import android.content.Context;
|
||||
|
||||
import com.android.launcher3.Launcher;
|
||||
import com.android.quickstep.util.SplitAnimationTimings;
|
||||
import com.android.quickstep.views.RecentsView;
|
||||
|
||||
/**
|
||||
@@ -26,10 +27,6 @@ import com.android.quickstep.views.RecentsView;
|
||||
* pinned and user is selecting the second one
|
||||
*/
|
||||
public class SplitScreenSelectState extends OverviewState {
|
||||
public static final int ENTER_DURATION = 866;
|
||||
public static final int EXIT_DURATION = 500;
|
||||
// TODO: Add ability to differentiate between Split > Home and Split > Confirmed timings
|
||||
|
||||
public SplitScreenSelectState(int id) {
|
||||
super(id);
|
||||
}
|
||||
@@ -47,6 +44,8 @@ public class SplitScreenSelectState extends OverviewState {
|
||||
|
||||
@Override
|
||||
public int getTransitionDuration(Context context, boolean isToState) {
|
||||
return isToState ? ENTER_DURATION : EXIT_DURATION;
|
||||
return isToState
|
||||
? SplitAnimationTimings.ENTER_DURATION
|
||||
: SplitAnimationTimings.ABORT_DURATION;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,89 @@
|
||||
/*
|
||||
* Copyright (C) 2022 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.util;
|
||||
|
||||
import static com.android.launcher3.anim.Interpolators.DEACCEL_2;
|
||||
|
||||
import android.view.animation.Interpolator;
|
||||
|
||||
/**
|
||||
* Timings for the Overview > OverviewSplitSelect animation.
|
||||
*/
|
||||
public class OverviewToSplitTimings implements SplitAnimationTimings {
|
||||
public int getThumbnailFadeToGrayStart() { return 0; }
|
||||
public int getThumbnailFadeToGrayEnd() { return 133; }
|
||||
public int getDockedIconFadeInStart() { return 167; }
|
||||
public int getDockedIconFadeInEnd() { return 250; }
|
||||
public int getStagedRectSlideStart() { return 0; }
|
||||
public int getStagedRectSlideEnd() { return 417; }
|
||||
public int getGridSlideStart() { return 67; }
|
||||
public int getGridSlideStagger() { return 16; }
|
||||
public int getGridSlideDuration() { return 500; }
|
||||
public int getActionsFadeStart() { return 0; }
|
||||
public int getActionsFadeEnd() { return 83; }
|
||||
public int getIconFadeStart() { return 0; }
|
||||
public int getIconFadeEnd() { return 83; }
|
||||
public int getInstructionsContainerFadeInStart() { return 167; }
|
||||
public int getInstructionsContainerFadeInEnd() { return 250; }
|
||||
public int getInstructionsTextFadeInStart() { return 217; }
|
||||
public int getInstructionsTextFadeInEnd() { return 300; }
|
||||
public int getInstructionsUnfoldStart() { return 167; }
|
||||
public int getInstructionsUnfoldEnd() { return 500; }
|
||||
|
||||
public int getDuration() { return ENTER_DURATION; }
|
||||
public Interpolator getStagedRectSlideInterpolator() { return DEACCEL_2; }
|
||||
|
||||
public float getGridSlideStartOffset() {
|
||||
return (float) getGridSlideStart() / getDuration();
|
||||
}
|
||||
public float getGridSlideStaggerOffset() {
|
||||
return (float) getGridSlideStagger() / getDuration();
|
||||
}
|
||||
public float getGridSlideDurationOffset() {
|
||||
return (float) getGridSlideDuration() / getDuration();
|
||||
}
|
||||
public float getActionsFadeStartOffset() {
|
||||
return (float) getActionsFadeStart() / getDuration();
|
||||
}
|
||||
public float getActionsFadeEndOffset() {
|
||||
return (float) getActionsFadeEnd() / getDuration();
|
||||
}
|
||||
public float getIconFadeStartOffset() {
|
||||
return (float) getIconFadeStart() / getDuration();
|
||||
}
|
||||
public float getIconFadeEndOffset() {
|
||||
return (float) getIconFadeEnd() / getDuration();
|
||||
}
|
||||
public float getInstructionsContainerFadeInStartOffset() {
|
||||
return (float) getInstructionsContainerFadeInStart() / getDuration();
|
||||
}
|
||||
public float getInstructionsContainerFadeInEndOffset() {
|
||||
return (float) getInstructionsContainerFadeInEnd() / getDuration();
|
||||
}
|
||||
public float getInstructionsTextFadeInStartOffset() {
|
||||
return (float) getInstructionsTextFadeInStart() / getDuration();
|
||||
}
|
||||
public float getInstructionsTextFadeInEndOffset() {
|
||||
return (float) getInstructionsTextFadeInEnd() / getDuration();
|
||||
}
|
||||
public float getInstructionsUnfoldStartOffset() {
|
||||
return (float) getInstructionsUnfoldStart() / getDuration();
|
||||
}
|
||||
public float getInstructionsUnfoldEndOffset() {
|
||||
return (float) getInstructionsUnfoldEnd() / getDuration();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
* Copyright (C) 2022 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.util;
|
||||
|
||||
import android.view.animation.Interpolator;
|
||||
|
||||
/**
|
||||
* An interface that supports the centralization of timing information for splitscreen animations.
|
||||
*/
|
||||
public interface SplitAnimationTimings {
|
||||
int ENTER_DURATION = 866;
|
||||
int ABORT_DURATION = 500;
|
||||
int CONFIRM_DURATION = 383;
|
||||
|
||||
SplitAnimationTimings OVERVIEW_TO_SPLIT = new OverviewToSplitTimings();
|
||||
SplitAnimationTimings SPLIT_TO_CONFIRM = new SplitToConfirmTimings();
|
||||
|
||||
// Shared methods
|
||||
int getDuration();
|
||||
int getThumbnailFadeToGrayStart();
|
||||
int getThumbnailFadeToGrayEnd();
|
||||
int getDockedIconFadeInStart();
|
||||
int getDockedIconFadeInEnd();
|
||||
int getStagedRectSlideStart();
|
||||
int getStagedRectSlideEnd();
|
||||
Interpolator getStagedRectSlideInterpolator();
|
||||
default float getThumbnailFadeToGrayStartOffset() {
|
||||
return (float) getThumbnailFadeToGrayStart() / getDuration();
|
||||
}
|
||||
default float getThumbnailFadeToGrayEndOffset() {
|
||||
return (float) getThumbnailFadeToGrayEnd() / getDuration();
|
||||
}
|
||||
default float getDockedIconFadeInStartOffset() {
|
||||
return (float) getDockedIconFadeInStart() / getDuration();
|
||||
}
|
||||
default float getDockedIconFadeInEndOffset() {
|
||||
return (float) getDockedIconFadeInEnd() / getDuration();
|
||||
}
|
||||
default float getStagedRectSlideStartOffset() {
|
||||
return (float) getStagedRectSlideStart() / getDuration();
|
||||
}
|
||||
default float getStagedRectSlideEndOffset() {
|
||||
return (float) getStagedRectSlideEnd() / getDuration();
|
||||
}
|
||||
|
||||
// Defaults for OverviewToSplit
|
||||
default float getGridSlideStartOffset() { return 0; }
|
||||
default float getGridSlideStaggerOffset() { return 0; }
|
||||
default float getGridSlideDurationOffset() { return 0; }
|
||||
default float getActionsFadeStartOffset() { return 0; }
|
||||
default float getActionsFadeEndOffset() { return 0; }
|
||||
default float getIconFadeStartOffset() { return 0; }
|
||||
default float getIconFadeEndOffset() { return 0; }
|
||||
default float getInstructionsContainerFadeInStartOffset() { return 0; }
|
||||
default float getInstructionsContainerFadeInEndOffset() { return 0; }
|
||||
default float getInstructionsTextFadeInStartOffset() { return 0; }
|
||||
default float getInstructionsTextFadeInEndOffset() { return 0; }
|
||||
default float getInstructionsUnfoldStartOffset() { return 0; }
|
||||
default float getInstructionsUnfoldEndOffset() { return 0; }
|
||||
|
||||
// Defaults for SplitToConfirm
|
||||
default float getInstructionsFadeStartOffset() { return 0; }
|
||||
default float getInstructionsFadeEndOffset() { return 0; }
|
||||
}
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright (C) 2022 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.util;
|
||||
|
||||
import static com.android.launcher3.anim.Interpolators.LINEAR;
|
||||
|
||||
import android.view.animation.Interpolator;
|
||||
|
||||
/**
|
||||
* Timings for the OverviewSplitSelect > confirmed animation.
|
||||
*/
|
||||
public class SplitToConfirmTimings implements SplitAnimationTimings {
|
||||
public int getThumbnailFadeToGrayStart() { return 0; }
|
||||
public int getThumbnailFadeToGrayEnd() { return 133; }
|
||||
public int getDockedIconFadeInStart() { return 167; }
|
||||
public int getDockedIconFadeInEnd() { return 250; }
|
||||
public int getStagedRectSlideStart() { return 0; }
|
||||
public int getStagedRectSlideEnd() { return 383; }
|
||||
public int getInstructionsFadeStart() { return 0; }
|
||||
public int getInstructionsFadeEnd() { return 67; }
|
||||
|
||||
public int getDuration() { return CONFIRM_DURATION; }
|
||||
public Interpolator getStagedRectSlideInterpolator() { return LINEAR; }
|
||||
|
||||
public float getInstructionsFadeStartOffset() {
|
||||
return (float) getInstructionsFadeStart() / getDuration();
|
||||
}
|
||||
public float getInstructionsFadeEndOffset() {
|
||||
return (float) getInstructionsFadeEnd() / getDuration();
|
||||
}
|
||||
}
|
||||
@@ -2,7 +2,6 @@ package com.android.quickstep.views;
|
||||
|
||||
import static com.android.launcher3.AbstractFloatingView.TYPE_TASK_MENU;
|
||||
import static com.android.launcher3.anim.Interpolators.ACCEL;
|
||||
import static com.android.launcher3.anim.Interpolators.DEACCEL_2;
|
||||
import static com.android.launcher3.anim.Interpolators.INSTANT;
|
||||
import static com.android.launcher3.anim.Interpolators.LINEAR;
|
||||
import static com.android.launcher3.anim.Interpolators.clampToProgress;
|
||||
@@ -31,10 +30,10 @@ import com.android.launcher3.Utilities;
|
||||
import com.android.launcher3.anim.PendingAnimation;
|
||||
import com.android.launcher3.statemanager.StatefulActivity;
|
||||
import com.android.launcher3.touch.PagedOrientationHandler;
|
||||
import com.android.launcher3.uioverrides.states.SplitScreenSelectState;
|
||||
import com.android.launcher3.util.SplitConfigurationOptions;
|
||||
import com.android.launcher3.views.BaseDragLayer;
|
||||
import com.android.quickstep.util.MultiValueUpdateListener;
|
||||
import com.android.quickstep.util.SplitAnimationTimings;
|
||||
import com.android.quickstep.util.TaskCornerRadius;
|
||||
import com.android.systemui.shared.system.QuickStepContract;
|
||||
|
||||
@@ -44,38 +43,14 @@ import com.android.systemui.shared.system.QuickStepContract;
|
||||
* which will have the thumbnail from the provided existing TaskView overlaying the taskview itself.
|
||||
*
|
||||
* Can then animate the taskview using
|
||||
* {@link #addAnimation(PendingAnimation, RectF, Rect, boolean, boolean)}
|
||||
* {@link #addStagingAnimation(PendingAnimation, RectF, Rect, boolean, boolean)} or
|
||||
* {@link #addConfirmAnimation(PendingAnimation, RectF, Rect, boolean, boolean)}
|
||||
* giving a starting and ending bounds. Currently this is set to use the split placeholder view,
|
||||
* but it could be generified.
|
||||
*
|
||||
* TODO: Figure out how to copy thumbnail data from existing TaskView to this view.
|
||||
*/
|
||||
public class FloatingTaskView extends FrameLayout {
|
||||
private static final int OVERVIEW_TO_SPLIT_THUMBNAIL_FADE_TO_GRAY_START = 0;
|
||||
private static final int OVERVIEW_TO_SPLIT_THUMBNAIL_FADE_TO_GRAY_END = 133;
|
||||
private static final int OVERVIEW_TO_SPLIT_DOCKED_ICON_FADE_IN_START = 167;
|
||||
private static final int OVERVIEW_TO_SPLIT_DOCKED_ICON_FADE_IN_END = 250;
|
||||
private static final int OVERVIEW_TO_SPLIT_STAGED_RECT_SLIDE_START = 0;
|
||||
private static final int OVERVIEW_TO_SPLIT_STAGED_RECT_SLIDE_END = 417;
|
||||
|
||||
private static final float OVERVIEW_TO_SPLIT_THUMBNAIL_FADE_TO_GRAY_START_OFFSET =
|
||||
(float) OVERVIEW_TO_SPLIT_THUMBNAIL_FADE_TO_GRAY_START
|
||||
/ SplitScreenSelectState.ENTER_DURATION;
|
||||
private static final float OVERVIEW_TO_SPLIT_THUMBNAIL_FADE_TO_GRAY_END_OFFSET =
|
||||
(float) OVERVIEW_TO_SPLIT_THUMBNAIL_FADE_TO_GRAY_END
|
||||
/ SplitScreenSelectState.ENTER_DURATION;
|
||||
private static final float OVERVIEW_TO_SPLIT_DOCKED_ICON_FADE_IN_START_OFFSET =
|
||||
(float) OVERVIEW_TO_SPLIT_DOCKED_ICON_FADE_IN_START
|
||||
/ SplitScreenSelectState.ENTER_DURATION;
|
||||
private static final float OVERVIEW_TO_SPLIT_DOCKED_ICON_FADE_IN_END_OFFSET =
|
||||
(float) OVERVIEW_TO_SPLIT_DOCKED_ICON_FADE_IN_END
|
||||
/ SplitScreenSelectState.ENTER_DURATION;
|
||||
private static final float OVERVIEW_TO_SPLIT_STAGED_RECT_SLIDE_START_OFFSET =
|
||||
(float) OVERVIEW_TO_SPLIT_STAGED_RECT_SLIDE_START
|
||||
/ SplitScreenSelectState.ENTER_DURATION;
|
||||
private static final float OVERVIEW_TO_SPLIT_STAGED_RECT_SLIDE_END_OFFSET =
|
||||
(float) OVERVIEW_TO_SPLIT_STAGED_RECT_SLIDE_END
|
||||
/ SplitScreenSelectState.ENTER_DURATION;
|
||||
|
||||
public static final FloatProperty<FloatingTaskView> PRIMARY_TRANSLATE_OFFSCREEN =
|
||||
new FloatProperty<FloatingTaskView>("floatingTaskPrimaryTranslateOffscreen") {
|
||||
@@ -236,8 +211,34 @@ public class FloatingTaskView extends FrameLayout {
|
||||
layout(left, lp.topMargin, left + lp.width, lp.topMargin + lp.height);
|
||||
}
|
||||
|
||||
public void addAnimation(PendingAnimation animation, RectF startingBounds, Rect endBounds,
|
||||
boolean fadeWithThumbnail, boolean isStagedTask) {
|
||||
/**
|
||||
* Animates a FloatingTaskThumbnailView and its overlapping SplitPlaceholderView when a split
|
||||
* is staged.
|
||||
*/
|
||||
public void addStagingAnimation(PendingAnimation animation, RectF startingBounds,
|
||||
Rect endBounds, boolean fadeWithThumbnail, boolean isStagedTask) {
|
||||
addAnimation(animation, startingBounds, endBounds, fadeWithThumbnail, isStagedTask,
|
||||
SplitAnimationTimings.OVERVIEW_TO_SPLIT);
|
||||
}
|
||||
|
||||
/**
|
||||
* Animates the FloatingTaskThumbnailView and SplitPlaceholderView for the two thumbnails
|
||||
* when a split is confirmed.
|
||||
*/
|
||||
public void addConfirmAnimation(PendingAnimation animation, RectF startingBounds,
|
||||
Rect endBounds, boolean fadeWithThumbnail, boolean isStagedTask) {
|
||||
addAnimation(animation, startingBounds, endBounds, fadeWithThumbnail, isStagedTask,
|
||||
SplitAnimationTimings.SPLIT_TO_CONFIRM);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets up and builds a split staging animation.
|
||||
* Called by {@link #addStagingAnimation(PendingAnimation, RectF, Rect, boolean, boolean)} and
|
||||
* {@link #addConfirmAnimation(PendingAnimation, RectF, Rect, boolean, boolean)}.
|
||||
*/
|
||||
public void addAnimation(PendingAnimation animation, RectF startingBounds,
|
||||
Rect endBounds, boolean fadeWithThumbnail, boolean isStagedTask,
|
||||
SplitAnimationTimings timings) {
|
||||
mFullscreenParams.setIsStagedTask(isStagedTask);
|
||||
final BaseDragLayer dragLayer = mActivity.getDragLayer();
|
||||
int[] dragLayerBounds = new int[2];
|
||||
@@ -251,49 +252,54 @@ public class FloatingTaskView extends FrameLayout {
|
||||
RectF floatingTaskViewBounds = new RectF();
|
||||
|
||||
if (fadeWithThumbnail) {
|
||||
// This code block runs when animating from Overview > OverviewSplitSelect
|
||||
// And for the second thumbnail on confirm
|
||||
// This code block runs for the placeholder view during Overview > OverviewSplitSelect
|
||||
// and for the selected (secondary) thumbnail during OverviewSplitSelect > Confirmed
|
||||
|
||||
// FloatingTaskThumbnailView: thumbnail fades out to transparent
|
||||
animation.setViewAlpha(mThumbnailView, 0, clampToProgress(LINEAR,
|
||||
OVERVIEW_TO_SPLIT_THUMBNAIL_FADE_TO_GRAY_START_OFFSET,
|
||||
OVERVIEW_TO_SPLIT_THUMBNAIL_FADE_TO_GRAY_END_OFFSET));
|
||||
timings.getThumbnailFadeToGrayStartOffset(),
|
||||
timings.getThumbnailFadeToGrayEndOffset()));
|
||||
|
||||
// SplitPlaceholderView: gray background fades in at the same time, then new icon fades
|
||||
// in
|
||||
// SplitPlaceholderView: gray background fades in at same time, then new icon fades in
|
||||
animation.setViewAlpha(mSplitPlaceholderView, 1, clampToProgress(LINEAR,
|
||||
OVERVIEW_TO_SPLIT_THUMBNAIL_FADE_TO_GRAY_START_OFFSET,
|
||||
OVERVIEW_TO_SPLIT_THUMBNAIL_FADE_TO_GRAY_END_OFFSET));
|
||||
timings.getThumbnailFadeToGrayStartOffset(),
|
||||
timings.getThumbnailFadeToGrayEndOffset()));
|
||||
animation.setViewAlpha(mSplitPlaceholderView.getIconView(), 1, clampToProgress(
|
||||
LINEAR, OVERVIEW_TO_SPLIT_DOCKED_ICON_FADE_IN_START_OFFSET,
|
||||
OVERVIEW_TO_SPLIT_DOCKED_ICON_FADE_IN_END_OFFSET));
|
||||
LINEAR,
|
||||
timings.getDockedIconFadeInStartOffset(),
|
||||
timings.getDockedIconFadeInEndOffset()));
|
||||
} else if (isStagedTask) {
|
||||
// This code block runs when animating from Normal > OverviewSplitSelect
|
||||
// and for the first thumbnail on confirm
|
||||
// This code block runs for the placeholder view during Normal > OverviewSplitSelect
|
||||
// and for the placeholder (primary) thumbnail during OverviewSplitSelect > Confirmed
|
||||
|
||||
// Fade in the placeholder view when split is initiated from homescreen / all apps
|
||||
// Fade in the placeholder view during Normal > OverviewSplitSelect
|
||||
if (mSplitPlaceholderView.getAlpha() == 0) {
|
||||
animation.setViewAlpha(mSplitPlaceholderView, 0.3f, INSTANT);
|
||||
animation.setViewAlpha(mSplitPlaceholderView, 1, ACCEL);
|
||||
}
|
||||
|
||||
// No-op for placeholder during OverviewSplitSelect > Confirmed, alpha should be set
|
||||
}
|
||||
|
||||
|
||||
MultiValueUpdateListener listener = new MultiValueUpdateListener() {
|
||||
// SplitPlaceholderView: rectangle translates and stretches to new position
|
||||
final FloatProp mDx = new FloatProp(0, prop.dX, 0, animDuration,
|
||||
clampToProgress(DEACCEL_2, OVERVIEW_TO_SPLIT_STAGED_RECT_SLIDE_START_OFFSET,
|
||||
OVERVIEW_TO_SPLIT_STAGED_RECT_SLIDE_END_OFFSET));
|
||||
clampToProgress(timings.getStagedRectSlideInterpolator(),
|
||||
timings.getStagedRectSlideStartOffset(),
|
||||
timings.getStagedRectSlideEndOffset()));
|
||||
final FloatProp mDy = new FloatProp(0, prop.dY, 0, animDuration,
|
||||
clampToProgress(DEACCEL_2, OVERVIEW_TO_SPLIT_STAGED_RECT_SLIDE_START_OFFSET,
|
||||
OVERVIEW_TO_SPLIT_STAGED_RECT_SLIDE_END_OFFSET));
|
||||
clampToProgress(timings.getStagedRectSlideInterpolator(),
|
||||
timings.getStagedRectSlideStartOffset(),
|
||||
timings.getStagedRectSlideEndOffset()));
|
||||
final FloatProp mTaskViewScaleX = new FloatProp(1f, prop.finalTaskViewScaleX, 0,
|
||||
animDuration, clampToProgress(DEACCEL_2,
|
||||
OVERVIEW_TO_SPLIT_STAGED_RECT_SLIDE_START_OFFSET,
|
||||
OVERVIEW_TO_SPLIT_STAGED_RECT_SLIDE_END_OFFSET));
|
||||
animDuration, clampToProgress(timings.getStagedRectSlideInterpolator(),
|
||||
timings.getStagedRectSlideStartOffset(),
|
||||
timings.getStagedRectSlideEndOffset()));
|
||||
final FloatProp mTaskViewScaleY = new FloatProp(1f, prop.finalTaskViewScaleY, 0,
|
||||
animDuration, clampToProgress(DEACCEL_2,
|
||||
OVERVIEW_TO_SPLIT_STAGED_RECT_SLIDE_START_OFFSET,
|
||||
OVERVIEW_TO_SPLIT_STAGED_RECT_SLIDE_END_OFFSET));
|
||||
animDuration, clampToProgress(timings.getStagedRectSlideInterpolator(),
|
||||
timings.getStagedRectSlideStartOffset(),
|
||||
timings.getStagedRectSlideEndOffset()));
|
||||
@Override
|
||||
public void onUpdate(float percent, boolean initOnly) {
|
||||
// Calculate the icon position.
|
||||
@@ -305,6 +311,7 @@ public class FloatingTaskView extends FrameLayout {
|
||||
update(floatingTaskViewBounds, percent);
|
||||
}
|
||||
};
|
||||
|
||||
transitionAnimator.addUpdateListener(listener);
|
||||
}
|
||||
|
||||
|
||||
@@ -39,7 +39,7 @@ import static com.android.launcher3.anim.Interpolators.EMPHASIZED_DECELERATE;
|
||||
import static com.android.launcher3.anim.Interpolators.FAST_OUT_SLOW_IN;
|
||||
import static com.android.launcher3.anim.Interpolators.FINAL_FRAME;
|
||||
import static com.android.launcher3.anim.Interpolators.LINEAR;
|
||||
import static com.android.launcher3.anim.Interpolators.OVERSHOOT_0_85;
|
||||
import static com.android.launcher3.anim.Interpolators.OVERSHOOT_0_75;
|
||||
import static com.android.launcher3.anim.Interpolators.clampToProgress;
|
||||
import static com.android.launcher3.config.FeatureFlags.ENABLE_QUICKSTEP_LIVE_TILE;
|
||||
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_OVERVIEW_ACTIONS_SPLIT;
|
||||
@@ -142,7 +142,6 @@ import com.android.launcher3.statemanager.BaseState;
|
||||
import com.android.launcher3.statemanager.StatefulActivity;
|
||||
import com.android.launcher3.touch.OverScroll;
|
||||
import com.android.launcher3.touch.PagedOrientationHandler;
|
||||
import com.android.launcher3.uioverrides.states.SplitScreenSelectState;
|
||||
import com.android.launcher3.util.DynamicResource;
|
||||
import com.android.launcher3.util.IntArray;
|
||||
import com.android.launcher3.util.IntSet;
|
||||
@@ -175,6 +174,7 @@ import com.android.quickstep.util.ActiveGestureLog;
|
||||
import com.android.quickstep.util.GroupTask;
|
||||
import com.android.quickstep.util.LayoutUtils;
|
||||
import com.android.quickstep.util.RecentsOrientedState;
|
||||
import com.android.quickstep.util.SplitAnimationTimings;
|
||||
import com.android.quickstep.util.SplitScreenBounds;
|
||||
import com.android.quickstep.util.SplitSelectStateController;
|
||||
import com.android.quickstep.util.SurfaceTransactionApplier;
|
||||
@@ -419,54 +419,6 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
private static final float ANIMATION_DISMISS_PROGRESS_MIDPOINT = 0.5f;
|
||||
private static final float END_DISMISS_TRANSLATION_INTERPOLATION_OFFSET = 0.75f;
|
||||
|
||||
private static final int OVERVIEW_TO_SPLIT_THUMBNAIL_SLIDE_START = 67;
|
||||
private static final int OVERVIEW_TO_SPLIT_THUMBNAIL_SLIDE_OFFSET = 16;
|
||||
private static final int SPRING_DISMISS_TRANSLATION_DURATION = 500;
|
||||
|
||||
private static final float INITIAL_SPRING_DISMISS_TRANSLATION_INTERPOLATION_OFFSET =
|
||||
(float) OVERVIEW_TO_SPLIT_THUMBNAIL_SLIDE_START
|
||||
/ SplitScreenSelectState.ENTER_DURATION;
|
||||
private static final float ADDITIONAL_SPRING_DISMISS_TRANSLATION_INTERPOLATION_OFFSET =
|
||||
(float) OVERVIEW_TO_SPLIT_THUMBNAIL_SLIDE_OFFSET
|
||||
/ SplitScreenSelectState.ENTER_DURATION;
|
||||
private static final float END_SPRING_DISMISS_TRANSLATION_INTERPOLATION_OFFSET =
|
||||
(float) SPRING_DISMISS_TRANSLATION_DURATION
|
||||
/ SplitScreenSelectState.ENTER_DURATION;
|
||||
|
||||
private static final int OVERVIEW_TO_SPLIT_ICON_FADE_START = 0;
|
||||
private static final int OVERVIEW_TO_SPLIT_ICON_FADE_END = 83;
|
||||
private static final int OVERVIEW_TO_SPLIT_INSTRUCTIONS_CONTAINER_FADE_IN_START = 167;
|
||||
private static final int OVERVIEW_TO_SPLIT_INSTRUCTIONS_CONTAINER_FADE_IN_END = 250;
|
||||
private static final int OVERVIEW_TO_SPLIT_INSTRUCTIONS_TEXT_FADE_IN_START = 217;
|
||||
private static final int OVERVIEW_TO_SPLIT_INSTRUCTIONS_TEXT_FADE_IN_END = 300;
|
||||
private static final int OVERVIEW_TO_SPLIT_INSTRUCTIONS_UNFOLD_START = 167;
|
||||
private static final int OVERVIEW_TO_SPLIT_INSTRUCTIONS_UNFOLD_END = 500;
|
||||
|
||||
private static final float OVERVIEW_TO_SPLIT_ICON_FADE_START_OFFSET =
|
||||
(float) OVERVIEW_TO_SPLIT_ICON_FADE_START
|
||||
/ SplitScreenSelectState.ENTER_DURATION;
|
||||
private static final float OVERVIEW_TO_SPLIT_ICON_FADE_END_OFFSET =
|
||||
(float) OVERVIEW_TO_SPLIT_ICON_FADE_END
|
||||
/ SplitScreenSelectState.ENTER_DURATION;
|
||||
private static final float OVERVIEW_TO_SPLIT_INSTRUCTIONS_CONTAINER_FADE_IN_START_OFFSET =
|
||||
(float) OVERVIEW_TO_SPLIT_INSTRUCTIONS_CONTAINER_FADE_IN_START
|
||||
/ SplitScreenSelectState.ENTER_DURATION;
|
||||
private static final float OVERVIEW_TO_SPLIT_INSTRUCTIONS_CONTAINER_FADE_IN_END_OFFSET =
|
||||
(float) OVERVIEW_TO_SPLIT_INSTRUCTIONS_CONTAINER_FADE_IN_END
|
||||
/ SplitScreenSelectState.ENTER_DURATION;
|
||||
private static final float OVERVIEW_TO_SPLIT_INSTRUCTIONS_TEXT_FADE_IN_START_OFFSET =
|
||||
(float) OVERVIEW_TO_SPLIT_INSTRUCTIONS_TEXT_FADE_IN_START
|
||||
/ SplitScreenSelectState.ENTER_DURATION;
|
||||
private static final float OVERVIEW_TO_SPLIT_INSTRUCTIONS_TEXT_FADE_IN_END_OFFSET =
|
||||
(float) OVERVIEW_TO_SPLIT_INSTRUCTIONS_TEXT_FADE_IN_END
|
||||
/ SplitScreenSelectState.ENTER_DURATION;
|
||||
private static final float OVERVIEW_TO_SPLIT_INSTRUCTIONS_UNFOLD_START_OFFSET =
|
||||
(float) OVERVIEW_TO_SPLIT_INSTRUCTIONS_UNFOLD_START
|
||||
/ SplitScreenSelectState.ENTER_DURATION;
|
||||
private static final float OVERVIEW_TO_SPLIT_INSTRUCTIONS_UNFOLD_END_OFFSET =
|
||||
(float) OVERVIEW_TO_SPLIT_INSTRUCTIONS_UNFOLD_END
|
||||
/ SplitScreenSelectState.ENTER_DURATION;
|
||||
|
||||
private static final float SIGNIFICANT_MOVE_SCREEN_WIDTH_PERCENTAGE = 0.15f;
|
||||
|
||||
protected final RecentsOrientedState mOrientationState;
|
||||
@@ -2857,6 +2809,7 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
mOrientationHandler.getInitialSplitPlaceholderBounds(mSplitPlaceholderSize,
|
||||
mSplitPlaceholderInset, mActivity.getDeviceProfile(),
|
||||
mSplitSelectStateController.getActiveSplitStagePosition(), mTempRect);
|
||||
SplitAnimationTimings timings = SplitAnimationTimings.OVERVIEW_TO_SPLIT;
|
||||
|
||||
RectF startingTaskRect = new RectF();
|
||||
safeRemoveDragLayerView(mFirstFloatingTaskView);
|
||||
@@ -2864,21 +2817,21 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
// Split staging is initiated
|
||||
mSplitHiddenTaskView.setThumbnailVisibility(INVISIBLE);
|
||||
anim.setViewAlpha(mSplitHiddenTaskView.getIconView(), 0, clampToProgress(LINEAR,
|
||||
OVERVIEW_TO_SPLIT_ICON_FADE_START_OFFSET,
|
||||
OVERVIEW_TO_SPLIT_ICON_FADE_END_OFFSET));
|
||||
timings.getIconFadeStartOffset(),
|
||||
timings.getIconFadeEndOffset()));
|
||||
mFirstFloatingTaskView = FloatingTaskView.getFloatingTaskView(mActivity,
|
||||
mSplitHiddenTaskView.getThumbnail(),
|
||||
mSplitHiddenTaskView.getThumbnail().getThumbnail(),
|
||||
mSplitHiddenTaskView.getIconView().getDrawable(), startingTaskRect);
|
||||
mFirstFloatingTaskView.setAlpha(1);
|
||||
mFirstFloatingTaskView.addAnimation(anim, startingTaskRect, mTempRect,
|
||||
mFirstFloatingTaskView.addStagingAnimation(anim, startingTaskRect, mTempRect,
|
||||
true /* fadeWithThumbnail */, true /* isStagedTask */);
|
||||
} else {
|
||||
mFirstFloatingTaskView = FloatingTaskView.getFloatingTaskView(mActivity,
|
||||
mSplitSelectSource.view, null /* thumbnail */,
|
||||
mSplitSelectSource.drawable, startingTaskRect);
|
||||
mFirstFloatingTaskView.setAlpha(1);
|
||||
mFirstFloatingTaskView.addAnimation(anim, startingTaskRect, mTempRect,
|
||||
mFirstFloatingTaskView.addStagingAnimation(anim, startingTaskRect, mTempRect,
|
||||
false /* fadeWithThumbnail */, true /* isStagedTask */);
|
||||
}
|
||||
|
||||
@@ -2887,15 +2840,15 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
mSplitInstructionsView = SplitInstructionsView.getSplitInstructionsView(mActivity);
|
||||
mSplitInstructionsView.setAlpha(0);
|
||||
anim.setViewAlpha(mSplitInstructionsView, 1, clampToProgress(LINEAR,
|
||||
OVERVIEW_TO_SPLIT_INSTRUCTIONS_CONTAINER_FADE_IN_START_OFFSET,
|
||||
OVERVIEW_TO_SPLIT_INSTRUCTIONS_CONTAINER_FADE_IN_END_OFFSET));
|
||||
timings.getInstructionsContainerFadeInStartOffset(),
|
||||
timings.getInstructionsContainerFadeInEndOffset()));
|
||||
anim.setViewAlpha(mSplitInstructionsView.getTextView(), 1, clampToProgress(LINEAR,
|
||||
OVERVIEW_TO_SPLIT_INSTRUCTIONS_TEXT_FADE_IN_START_OFFSET,
|
||||
OVERVIEW_TO_SPLIT_INSTRUCTIONS_TEXT_FADE_IN_END_OFFSET));
|
||||
timings.getInstructionsTextFadeInStartOffset(),
|
||||
timings.getInstructionsTextFadeInEndOffset()));
|
||||
anim.addFloat(mSplitInstructionsView, mSplitInstructionsView.UNFOLD, 0.1f, 1,
|
||||
clampToProgress(EMPHASIZED_DECELERATE,
|
||||
OVERVIEW_TO_SPLIT_INSTRUCTIONS_UNFOLD_START_OFFSET,
|
||||
OVERVIEW_TO_SPLIT_INSTRUCTIONS_UNFOLD_END_OFFSET));
|
||||
timings.getInstructionsUnfoldStartOffset(),
|
||||
timings.getInstructionsUnfoldEndOffset()));
|
||||
|
||||
InteractionJankMonitorWrapper.begin(this,
|
||||
InteractionJankMonitorWrapper.CUJ_SPLIT_SCREEN_ENTER, "First tile selected");
|
||||
@@ -3184,24 +3137,26 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
: distanceFromDismissedTask;
|
||||
// Set timings based on if user is initiating splitscreen on the focused task,
|
||||
// or splitting/dismissing some other task.
|
||||
SplitAnimationTimings timings = SplitAnimationTimings.OVERVIEW_TO_SPLIT;
|
||||
float animationStartProgress = isStagingFocusedTask
|
||||
? Utilities.boundToRange(
|
||||
INITIAL_SPRING_DISMISS_TRANSLATION_INTERPOLATION_OFFSET
|
||||
+ ADDITIONAL_SPRING_DISMISS_TRANSLATION_INTERPOLATION_OFFSET
|
||||
* staggerColumn, 0f, dismissTranslationInterpolationEnd)
|
||||
timings.getGridSlideStartOffset()
|
||||
+ (timings.getGridSlideStaggerOffset() * staggerColumn),
|
||||
0f,
|
||||
dismissTranslationInterpolationEnd)
|
||||
: Utilities.boundToRange(
|
||||
INITIAL_DISMISS_TRANSLATION_INTERPOLATION_OFFSET
|
||||
+ ADDITIONAL_DISMISS_TRANSLATION_INTERPOLATION_OFFSET
|
||||
* staggerColumn, 0f, dismissTranslationInterpolationEnd);
|
||||
float animationEndProgress = isStagingFocusedTask
|
||||
? Utilities.boundToRange(
|
||||
INITIAL_SPRING_DISMISS_TRANSLATION_INTERPOLATION_OFFSET
|
||||
+ END_SPRING_DISMISS_TRANSLATION_INTERPOLATION_OFFSET
|
||||
+ ADDITIONAL_SPRING_DISMISS_TRANSLATION_INTERPOLATION_OFFSET
|
||||
* staggerColumn,
|
||||
0f, dismissTranslationInterpolationEnd)
|
||||
timings.getGridSlideStartOffset()
|
||||
+ (timings.getGridSlideStaggerOffset() * staggerColumn)
|
||||
+ timings.getGridSlideDurationOffset(),
|
||||
0f,
|
||||
dismissTranslationInterpolationEnd)
|
||||
: dismissTranslationInterpolationEnd;
|
||||
Interpolator dismissInterpolator = isStagingFocusedTask ? OVERSHOOT_0_85 : LINEAR;
|
||||
Interpolator dismissInterpolator = isStagingFocusedTask ? OVERSHOOT_0_75 : LINEAR;
|
||||
|
||||
if (taskView == nextFocusedTaskView) {
|
||||
// Enlarge the task to be focused next, and translate into focus position.
|
||||
@@ -4223,9 +4178,9 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
// TODO(194414938) starting bounds seem slightly off, investigate
|
||||
Rect firstTaskStartingBounds = new Rect();
|
||||
Rect firstTaskEndingBounds = mTempRect;
|
||||
int duration = mActivity.getStateManager().getState().getTransitionDuration(mActivity,
|
||||
false /* isToState */);
|
||||
PendingAnimation pendingAnimation = new PendingAnimation(duration);
|
||||
PendingAnimation pendingAnimation =
|
||||
new PendingAnimation(SplitAnimationTimings.CONFIRM_DURATION);
|
||||
SplitAnimationTimings timings = SplitAnimationTimings.SPLIT_TO_CONFIRM;
|
||||
|
||||
int halfDividerSize = getResources()
|
||||
.getDimensionPixelSize(R.dimen.multi_window_task_divider_size) / 2;
|
||||
@@ -4235,7 +4190,7 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
secondTaskEndingBounds);
|
||||
|
||||
mFirstFloatingTaskView.getBoundsOnScreen(firstTaskStartingBounds);
|
||||
mFirstFloatingTaskView.addAnimation(pendingAnimation,
|
||||
mFirstFloatingTaskView.addConfirmAnimation(pendingAnimation,
|
||||
new RectF(firstTaskStartingBounds), firstTaskEndingBounds,
|
||||
false /* fadeWithThumbnail */, true /* isStagedTask */);
|
||||
|
||||
@@ -4244,8 +4199,13 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
thumbnailView, thumbnailView.getThumbnail(),
|
||||
iconView.getDrawable(), secondTaskStartingBounds);
|
||||
mSecondFloatingTaskView.setAlpha(1);
|
||||
mSecondFloatingTaskView.addAnimation(pendingAnimation, secondTaskStartingBounds,
|
||||
mSecondFloatingTaskView.addConfirmAnimation(pendingAnimation, secondTaskStartingBounds,
|
||||
secondTaskEndingBounds, true /* fadeWithThumbnail */, false /* isStagedTask */);
|
||||
|
||||
pendingAnimation.setViewAlpha(mSplitInstructionsView, 0, clampToProgress(LINEAR,
|
||||
timings.getInstructionsFadeStartOffset(),
|
||||
timings.getInstructionsFadeEndOffset()));
|
||||
|
||||
pendingAnimation.addEndListener(aBoolean -> {
|
||||
mSplitSelectStateController.launchSplitTasks(
|
||||
aBoolean1 -> RecentsView.this.resetFromSplitSelectionState());
|
||||
|
||||
@@ -83,7 +83,7 @@ public class Interpolators {
|
||||
EXAGGERATED_EASE = new PathInterpolator(exaggeratedEase);
|
||||
}
|
||||
|
||||
public static final Interpolator OVERSHOOT_0_85 = new OvershootInterpolator(0.85f);
|
||||
public static final Interpolator OVERSHOOT_0_75 = new OvershootInterpolator(0.75f);
|
||||
public static final Interpolator OVERSHOOT_1_2 = new OvershootInterpolator(1.2f);
|
||||
public static final Interpolator OVERSHOOT_1_7 = new OvershootInterpolator(1.7f);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user