Merge "Update animations for TM-QPR: OverviewSplitSelect > Home transition" into tm-qpr-dev

This commit is contained in:
Jeremy Sim
2022-07-29 18:57:00 +00:00
committed by Android (Google) Code Review
9 changed files with 213 additions and 9 deletions

View File

@@ -23,16 +23,22 @@ import static com.android.launcher3.anim.Interpolators.LINEAR;
import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_FADE;
import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_MODAL;
import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_SCALE;
import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_SPLIT_SELECT_FLOATING_TASK_TRANSLATE_OFFSCREEN;
import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_SPLIT_SELECT_INSTRUCTIONS_FADE;
import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_TRANSLATE_X;
import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_TRANSLATE_Y;
import static com.android.launcher3.states.StateAnimationConfig.SKIP_OVERVIEW;
import static com.android.launcher3.testing.shared.TestProtocol.BAD_STATE;
import static com.android.quickstep.views.RecentsView.ADJACENT_PAGE_HORIZONTAL_OFFSET;
import static com.android.quickstep.views.RecentsView.FIRST_FLOATING_TASK_TRANSLATE_OFFSCREEN;
import static com.android.quickstep.views.RecentsView.OVERVIEW_PROGRESS;
import static com.android.quickstep.views.RecentsView.RECENTS_GRID_PROGRESS;
import static com.android.quickstep.views.RecentsView.RECENTS_SCALE_PROPERTY;
import static com.android.quickstep.views.RecentsView.SPLIT_INSTRUCTIONS_FADE;
import static com.android.quickstep.views.RecentsView.TASK_SECONDARY_TRANSLATION;
import android.graphics.Rect;
import android.graphics.RectF;
import android.util.FloatProperty;
import android.util.Log;
@@ -40,9 +46,12 @@ import androidx.annotation.NonNull;
import com.android.launcher3.BaseQuickstepLauncher;
import com.android.launcher3.LauncherState;
import com.android.launcher3.Utilities;
import com.android.launcher3.anim.PendingAnimation;
import com.android.launcher3.dragndrop.DragLayer;
import com.android.launcher3.statemanager.StateManager.StateHandler;
import com.android.launcher3.states.StateAnimationConfig;
import com.android.quickstep.views.FloatingTaskView;
import com.android.quickstep.views.RecentsView;
/**
@@ -106,6 +115,49 @@ public abstract class BaseRecentsViewStateController<T extends RecentsView>
setter.setFloat(mRecentsView, TASK_SECONDARY_TRANSLATION, 0f,
config.getInterpolator(ANIM_OVERVIEW_TRANSLATE_Y, LINEAR));
if (mRecentsView.isSplitSelectionActive()) {
// TODO (b/238651489): Refactor state management to avoid need for double check
FloatingTaskView floatingTask = mRecentsView.getFirstFloatingTaskView();
if (floatingTask != null) {
DragLayer dragLayer = mLauncher.getDragLayer();
RectF onScreenRectF = new RectF();
Utilities.getBoundsForViewInDragLayer(mLauncher.getDragLayer(), floatingTask,
new Rect(0, 0, floatingTask.getWidth(), floatingTask.getHeight()),
false, null, onScreenRectF);
// Get the part of the floatingTask that intersects with the DragLayer (i.e. the
// on-screen portion)
onScreenRectF.intersect(
dragLayer.getLeft(),
dragLayer.getTop(),
dragLayer.getRight(),
dragLayer.getBottom()
);
setter.setFloat(
mRecentsView,
FIRST_FLOATING_TASK_TRANSLATE_OFFSCREEN,
mRecentsView.getPagedOrientationHandler()
.getFloatingTaskOffscreenTranslationTarget(
floatingTask,
onScreenRectF,
floatingTask.getStagePosition(),
mLauncher.getDeviceProfile()
),
config.getInterpolator(
ANIM_OVERVIEW_SPLIT_SELECT_FLOATING_TASK_TRANSLATE_OFFSCREEN,
LINEAR
));
setter.setFloat(
mRecentsView,
SPLIT_INSTRUCTIONS_FADE,
1,
config.getInterpolator(
ANIM_OVERVIEW_SPLIT_SELECT_INSTRUCTIONS_FADE,
LINEAR
));
}
}
float recentsAlpha = toState.overviewUi ? 1 : 0;
Log.d(BAD_STATE, "BaseRecentsViewStateController setStateWithAnimationInternal toState="
+ toState + ", alpha=" + recentsAlpha);

View File

@@ -37,6 +37,10 @@ import com.android.quickstep.views.TaskView;
*/
public class OverviewState extends LauncherState {
private static final int OVERVIEW_SLIDE_IN_DURATION = 380;
private static final int OVERVIEW_POP_IN_DURATION = 250;
private static final int OVERVIEW_EXIT_DURATION = 250;
protected static final Rect sTempRect = new Rect();
private static final int STATE_FLAGS = FLAG_WORKSPACE_ICONS_CAN_BE_DRAGGED
@@ -57,8 +61,15 @@ public class OverviewState extends LauncherState {
@Override
public int getTransitionDuration(Context context, boolean isToState) {
// In gesture modes, overview comes in all the way from the side, so give it more time.
return DisplayController.getNavigationMode(context).hasGestures ? 380 : 250;
if (isToState) {
// In gesture modes, overview comes in all the way from the side, so give it more time.
return DisplayController.getNavigationMode(context).hasGestures
? OVERVIEW_SLIDE_IN_DURATION
: OVERVIEW_POP_IN_DURATION;
} else {
// When exiting Overview, exit quickly.
return OVERVIEW_EXIT_DURATION;
}
}
@Override

View File

@@ -22,13 +22,15 @@ import static com.android.launcher3.LauncherState.HINT_STATE;
import static com.android.launcher3.LauncherState.HINT_STATE_TWO_BUTTON;
import static com.android.launcher3.LauncherState.NORMAL;
import static com.android.launcher3.LauncherState.OVERVIEW;
import static com.android.launcher3.LauncherState.OVERVIEW_SPLIT_SELECT;
import static com.android.launcher3.WorkspaceStateTransitionAnimation.getWorkspaceSpringScaleAnimator;
import static com.android.launcher3.anim.Interpolators.ACCEL;
import static com.android.launcher3.anim.Interpolators.ACCEL_DEACCEL;
import static com.android.launcher3.anim.Interpolators.DEACCEL;
import static com.android.launcher3.anim.Interpolators.DEACCEL_1_7;
import static com.android.launcher3.anim.Interpolators.DEACCEL_3;
import static com.android.launcher3.anim.Interpolators.FAST_OUT_SLOW_IN;
import static com.android.launcher3.anim.Interpolators.EMPHASIZED_ACCELERATE;
import static com.android.launcher3.anim.Interpolators.EMPHASIZED_DECELERATE;
import static com.android.launcher3.anim.Interpolators.FINAL_FRAME;
import static com.android.launcher3.anim.Interpolators.INSTANT;
import static com.android.launcher3.anim.Interpolators.LINEAR;
@@ -39,6 +41,8 @@ import static com.android.launcher3.states.StateAnimationConfig.ANIM_DEPTH;
import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_ACTIONS_FADE;
import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_FADE;
import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_SCALE;
import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_SPLIT_SELECT_FLOATING_TASK_TRANSLATE_OFFSCREEN;
import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_SPLIT_SELECT_INSTRUCTIONS_FADE;
import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_TRANSLATE_X;
import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_TRANSLATE_Y;
import static com.android.launcher3.states.StateAnimationConfig.ANIM_SCRIM_FADE;
@@ -87,9 +91,16 @@ public class QuickstepAtomicAnimationFactory extends
public void prepareForAtomicAnimation(LauncherState fromState, LauncherState toState,
StateAnimationConfig config) {
RecentsView overview = mActivity.getOverviewPanel();
if (toState == NORMAL && fromState == OVERVIEW) {
if ((fromState == OVERVIEW || fromState == OVERVIEW_SPLIT_SELECT) && toState == NORMAL) {
if (fromState == OVERVIEW_SPLIT_SELECT) {
config.setInterpolator(ANIM_OVERVIEW_SPLIT_SELECT_FLOATING_TASK_TRANSLATE_OFFSCREEN,
clampToProgress(EMPHASIZED_ACCELERATE, 0, 0.4f));
config.setInterpolator(ANIM_OVERVIEW_SPLIT_SELECT_INSTRUCTIONS_FADE,
clampToProgress(LINEAR, 0, 0.33f));
}
config.setInterpolator(ANIM_OVERVIEW_ACTIONS_FADE, clampToProgress(LINEAR, 0, 0.25f));
config.setInterpolator(ANIM_SCRIM_FADE, LINEAR);
config.setInterpolator(ANIM_SCRIM_FADE, clampToProgress(LINEAR, 0.33f, 1));
config.setInterpolator(ANIM_WORKSPACE_SCALE, DEACCEL);
config.setInterpolator(ANIM_WORKSPACE_FADE, ACCEL);
@@ -98,8 +109,7 @@ public class QuickstepAtomicAnimationFactory extends
// Overview is going offscreen, so keep it at its current scale and opacity.
config.setInterpolator(ANIM_OVERVIEW_SCALE, FINAL_FRAME);
config.setInterpolator(ANIM_OVERVIEW_FADE, FINAL_FRAME);
config.setInterpolator(ANIM_OVERVIEW_TRANSLATE_X,
clampToProgress(FAST_OUT_SLOW_IN, 0, 0.75f));
config.setInterpolator(ANIM_OVERVIEW_TRANSLATE_X, EMPHASIZED_DECELERATE);
config.setInterpolator(ANIM_OVERVIEW_TRANSLATE_Y, FINAL_FRAME);
} else {
config.setInterpolator(ANIM_OVERVIEW_TRANSLATE_X, ACCEL_DEACCEL);

View File

@@ -260,6 +260,10 @@ public class FloatingTaskView extends FrameLayout {
mActivity.getDeviceProfile(), mStagePosition);
}
public int getStagePosition() {
return mStagePosition;
}
private static class SplitOverlayProperties {
private final float finalTaskViewScaleX;

View File

@@ -397,6 +397,39 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
}
};
public static final FloatProperty<RecentsView> FIRST_FLOATING_TASK_TRANSLATE_OFFSCREEN =
new FloatProperty<RecentsView>("firstFloatingTaskTranslateOffscreen") {
@Override
public void setValue(RecentsView view, float translation) {
view.getPagedOrientationHandler().setFloatingTaskPrimaryTranslation(
view.mFirstFloatingTaskView,
translation,
view.mActivity.getDeviceProfile()
);
}
@Override
public Float get(RecentsView view) {
return view.getPagedOrientationHandler().getFloatingTaskPrimaryTranslation(
view.mFirstFloatingTaskView,
view.mActivity.getDeviceProfile()
);
}
};
public static final FloatProperty<RecentsView> SPLIT_INSTRUCTIONS_FADE =
new FloatProperty<RecentsView>("splitInstructionsFade") {
@Override
public void setValue(RecentsView view, float fade) {
view.mSplitInstructionsView.setAlpha(1 - fade);
}
@Override
public Float get(RecentsView view) {
return 1 - view.mSplitInstructionsView.getAlpha();
}
};
// OverScroll constants
private static final int OVERSCROLL_PAGE_SNAP_ANIMATION_DURATION = 270;
@@ -5291,6 +5324,11 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
return mRecentsAnimationController;
}
@Nullable
public FloatingTaskView getFirstFloatingTaskView() {
return mFirstFloatingTaskView;
}
/** Update the current activity locus id to show the enabled state of Overview */
public void updateLocusId() {
String locusId = "Overview";

View File

@@ -64,6 +64,8 @@ public class StateAnimationConfig {
ANIM_DEPTH,
ANIM_OVERVIEW_ACTIONS_FADE,
ANIM_WORKSPACE_PAGE_TRANSLATE_X,
ANIM_OVERVIEW_SPLIT_SELECT_FLOATING_TASK_TRANSLATE_OFFSCREEN,
ANIM_OVERVIEW_SPLIT_SELECT_INSTRUCTIONS_FADE
})
@Retention(RetentionPolicy.SOURCE)
public @interface AnimType {}
@@ -84,8 +86,10 @@ public class StateAnimationConfig {
public static final int ANIM_DEPTH = 13;
public static final int ANIM_OVERVIEW_ACTIONS_FADE = 14;
public static final int ANIM_WORKSPACE_PAGE_TRANSLATE_X = 15;
public static final int ANIM_OVERVIEW_SPLIT_SELECT_FLOATING_TASK_TRANSLATE_OFFSCREEN = 17;
public static final int ANIM_OVERVIEW_SPLIT_SELECT_INSTRUCTIONS_FADE = 18;
private static final int ANIM_TYPES_COUNT = 17;
private static final int ANIM_TYPES_COUNT = 19;
protected final Interpolator[] mInterpolators = new Interpolator[ANIM_TYPES_COUNT];

View File

@@ -581,4 +581,22 @@ public class LandscapePagedViewHandler implements PagedOrientationHandler {
FloatProperty secondary, DeviceProfile deviceProfile) {
return new Pair<>(primary, secondary);
}
@Override
public float getFloatingTaskOffscreenTranslationTarget(View floatingTask, RectF onScreenRect,
@StagePosition int stagePosition, DeviceProfile dp) {
float currentTranslationY = floatingTask.getTranslationY();
return currentTranslationY - onScreenRect.height();
}
@Override
public void setFloatingTaskPrimaryTranslation(View floatingTask, float translation,
DeviceProfile dp) {
floatingTask.setTranslationY(translation);
}
@Override
public Float getFloatingTaskPrimaryTranslation(View floatingTask, DeviceProfile dp) {
return floatingTask.getTranslationY();
}
}

View File

@@ -34,9 +34,9 @@ import android.widget.LinearLayout;
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.util.SplitConfigurationOptions;
import com.android.launcher3.util.SplitConfigurationOptions.SplitBounds;
import com.android.launcher3.util.SplitConfigurationOptions.SplitPositionOption;
import com.android.launcher3.util.SplitConfigurationOptions.StagePosition;
import com.android.launcher3.util.SplitConfigurationOptions.SplitBounds;
import java.util.List;
@@ -242,6 +242,41 @@ public interface PagedOrientationHandler {
*/
void fixBoundsForHomeAnimStartRect(RectF outStartRect, DeviceProfile deviceProfile);
/**
* Determine the target translation for animating the FloatingTaskView out. This value could
* either be an x-coordinate or a y-coordinate, depending on which way the FloatingTaskView was
* docked.
*
* @param floatingTask The FloatingTaskView.
* @param onScreenRect The current on-screen dimensions of the FloatingTaskView.
* @param stagePosition STAGE_POSITION_TOP_OR_LEFT or STAGE_POSITION_BOTTOM_OR_RIGHT.
* @param dp The device profile.
* @return A float. When an animation translates the FloatingTaskView to this position, it will
* appear to tuck away off the edge of the screen.
*/
float getFloatingTaskOffscreenTranslationTarget(View floatingTask, RectF onScreenRect,
@StagePosition int stagePosition, DeviceProfile dp);
/**
* Sets the translation of a FloatingTaskView along its "slide-in/slide-out" axis (could be
* either x or y), depending on how the view is oriented.
*
* @param floatingTask The FloatingTaskView to be translated.
* @param translation The target translation value.
* @param dp The current device profile.
*/
void setFloatingTaskPrimaryTranslation(View floatingTask, float translation, DeviceProfile dp);
/**
* Gets the translation of a FloatingTaskView along its "slide-in/slide-out" axis (could be
* either x or y), depending on how the view is oriented.
*
* @param floatingTask The FloatingTaskView in question.
* @param dp The current device profile.
* @return The current translation value.
*/
Float getFloatingTaskPrimaryTranslation(View floatingTask, DeviceProfile dp);
class ChildBounds {
public final int primaryDimension;

View File

@@ -757,4 +757,36 @@ public class PortraitPagedViewHandler implements PagedOrientationHandler {
return new Pair<>(secondary, primary);
}
}
@Override
public float getFloatingTaskOffscreenTranslationTarget(View floatingTask, RectF onScreenRect,
@StagePosition int stagePosition, DeviceProfile dp) {
if (dp.isLandscape) {
float currentTranslationX = floatingTask.getTranslationX();
return stagePosition == STAGE_POSITION_TOP_OR_LEFT
? currentTranslationX - onScreenRect.width()
: currentTranslationX + onScreenRect.width();
} else {
float currentTranslationY = floatingTask.getTranslationY();
return currentTranslationY - onScreenRect.height();
}
}
@Override
public void setFloatingTaskPrimaryTranslation(View floatingTask, float translation,
DeviceProfile dp) {
if (dp.isLandscape) {
floatingTask.setTranslationX(translation);
} else {
floatingTask.setTranslationY(translation);
}
}
@Override
public Float getFloatingTaskPrimaryTranslation(View floatingTask, DeviceProfile dp) {
return dp.isLandscape
? floatingTask.getTranslationX()
: floatingTask.getTranslationY();
}
}