mirror of
https://github.com/LawnchairLauncher/lawnchair.git
synced 2026-02-20 19:38:21 +00:00
Merge "Update animations for TM-QPR: OverviewSplitSelect > Home transition" into tm-qpr-dev
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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";
|
||||
|
||||
@@ -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];
|
||||
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user