Merge "Adding support for skipping animation cancel on reapply" into main
This commit is contained in:
+1
-1
@@ -106,7 +106,7 @@ public class PortraitStatesTouchController extends AbstractStateChangeTouchContr
|
||||
protected StateAnimationConfig getConfigForStates(
|
||||
LauncherState fromState, LauncherState toState) {
|
||||
final StateAnimationConfig config = new StateAnimationConfig();
|
||||
config.userControlled = true;
|
||||
config.animProps |= StateAnimationConfig.USER_CONTROLLED;
|
||||
if (fromState == NORMAL && toState == ALL_APPS) {
|
||||
AllAppsSwipeController.applyNormalToAllAppsAnimConfig(mLauncher, config);
|
||||
} else if (fromState == ALL_APPS && toState == NORMAL) {
|
||||
|
||||
@@ -342,7 +342,7 @@ public class AllAppsTransitionController
|
||||
});
|
||||
}
|
||||
|
||||
if(FeatureFlags.ENABLE_PREMIUM_HAPTICS_ALL_APPS.get() && config.userControlled
|
||||
if (FeatureFlags.ENABLE_PREMIUM_HAPTICS_ALL_APPS.get() && config.isUserControlled()
|
||||
&& Utilities.ATLEAST_S) {
|
||||
if (toState == ALL_APPS) {
|
||||
builder.addOnFrameListener(
|
||||
@@ -367,7 +367,7 @@ public class AllAppsTransitionController
|
||||
|
||||
// need to decide depending on the release velocity
|
||||
Interpolator verticalProgressInterpolator = config.getInterpolator(ANIM_VERTICAL_PROGRESS,
|
||||
config.userControlled ? LINEAR : DECELERATE_1_7);
|
||||
config.isUserControlled() ? LINEAR : DECELERATE_1_7);
|
||||
Animator anim = createSpringAnimation(mProgress, targetProgress);
|
||||
anim.setInterpolator(verticalProgressInterpolator);
|
||||
builder.add(anim);
|
||||
|
||||
@@ -19,6 +19,7 @@ package com.android.launcher3.statemanager;
|
||||
import static android.animation.ValueAnimator.areAnimatorsEnabled;
|
||||
|
||||
import static com.android.launcher3.anim.AnimatorPlaybackController.callListenerCommandRecursively;
|
||||
import static com.android.launcher3.states.StateAnimationConfig.HANDLE_STATE_APPLY;
|
||||
import static com.android.launcher3.states.StateAnimationConfig.SKIP_ALL_ANIMATIONS;
|
||||
|
||||
import android.animation.Animator;
|
||||
@@ -36,6 +37,7 @@ import com.android.launcher3.anim.AnimatorPlaybackController;
|
||||
import com.android.launcher3.anim.PendingAnimation;
|
||||
import com.android.launcher3.states.StateAnimationConfig;
|
||||
import com.android.launcher3.states.StateAnimationConfig.AnimationFlags;
|
||||
import com.android.launcher3.states.StateAnimationConfig.AnimationPropertyFlags;
|
||||
import com.android.launcher3.testing.shared.TestProtocol;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
@@ -189,7 +191,7 @@ public class StateManager<STATE_TYPE extends BaseState<STATE_TYPE>> {
|
||||
|
||||
public void reapplyState(boolean cancelCurrentAnimation) {
|
||||
boolean wasInAnimation = mConfig.currentAnimation != null;
|
||||
if (cancelCurrentAnimation) {
|
||||
if (cancelCurrentAnimation && (mConfig.animProps & HANDLE_STATE_APPLY) == 0) {
|
||||
// Animation canceling can trigger a cleanup routine, causing problems when we are in a
|
||||
// launcher state that relies on member variable data. So if we are in one of those
|
||||
// states, accelerate the current animation to its end point rather than canceling it
|
||||
@@ -237,7 +239,7 @@ public class StateManager<STATE_TYPE extends BaseState<STATE_TYPE>> {
|
||||
listener.onAnimationEnd(null);
|
||||
}
|
||||
return;
|
||||
} else if ((!mConfig.userControlled && animated && mConfig.targetState == state)
|
||||
} else if ((!mConfig.isUserControlled() && animated && mConfig.targetState == state)
|
||||
|| mState.shouldPreserveDataStateOnReapply()) {
|
||||
// We are running the same animation as requested, and/or target state should not be
|
||||
// reset -- allow the current animation to complete instead of canceling it.
|
||||
@@ -343,7 +345,7 @@ public class StateManager<STATE_TYPE extends BaseState<STATE_TYPE>> {
|
||||
|
||||
public AnimatorPlaybackController createAnimationToNewWorkspace(STATE_TYPE state,
|
||||
StateAnimationConfig config) {
|
||||
config.userControlled = true;
|
||||
config.animProps |= StateAnimationConfig.USER_CONTROLLED;
|
||||
cancelAnimation();
|
||||
config.copyTo(mConfig);
|
||||
mConfig.playbackController = createAnimationToNewWorkspaceInternal(state)
|
||||
@@ -418,7 +420,7 @@ public class StateManager<STATE_TYPE extends BaseState<STATE_TYPE>> {
|
||||
}
|
||||
|
||||
public void moveToRestState(boolean isAnimated) {
|
||||
if (mConfig.currentAnimation != null && mConfig.userControlled) {
|
||||
if (mConfig.currentAnimation != null && mConfig.isUserControlled()) {
|
||||
// The user is doing something. Lets not mess it up
|
||||
return;
|
||||
}
|
||||
@@ -450,10 +452,18 @@ public class StateManager<STATE_TYPE extends BaseState<STATE_TYPE>> {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the provided controller as the current user controlled state animation
|
||||
*/
|
||||
public void setCurrentUserControlledAnimation(AnimatorPlaybackController controller) {
|
||||
setCurrentAnimation(controller, StateAnimationConfig.USER_CONTROLLED);
|
||||
}
|
||||
|
||||
public void setCurrentAnimation(AnimatorPlaybackController controller,
|
||||
@AnimationPropertyFlags int animationProps) {
|
||||
clearCurrentAnimation();
|
||||
setCurrentAnimation(controller.getTarget());
|
||||
mConfig.userControlled = true;
|
||||
mConfig.animProps = animationProps;
|
||||
mConfig.playbackController = controller;
|
||||
}
|
||||
|
||||
|
||||
@@ -126,16 +126,8 @@ public abstract class StatefulActivity<STATE_TYPE extends BaseState<STATE_TYPE>>
|
||||
|
||||
@Override
|
||||
public void reapplyUi() {
|
||||
reapplyUi(true /* cancelCurrentAnimation */);
|
||||
}
|
||||
|
||||
/**
|
||||
* Re-applies if any state transition is not running, optionally cancelling
|
||||
* the transition if requested.
|
||||
*/
|
||||
public void reapplyUi(boolean cancelCurrentAnimation) {
|
||||
getRootView().dispatchInsets();
|
||||
getStateManager().reapplyState(cancelCurrentAnimation);
|
||||
getStateManager().reapplyState(true /* cancelCurrentAnimation */);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -40,8 +40,19 @@ public class StateAnimationConfig {
|
||||
public static final int SKIP_DEPTH_CONTROLLER = 1 << 2;
|
||||
public static final int SKIP_SCRIM = 1 << 3;
|
||||
|
||||
@IntDef(flag = true, value = {
|
||||
USER_CONTROLLED,
|
||||
HANDLE_STATE_APPLY
|
||||
})
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
public @interface AnimationPropertyFlags {}
|
||||
// Indicates that the animation is controlled by the user
|
||||
public static final int USER_CONTROLLED = 1 << 0;
|
||||
// Indicates that he animation can survive state UI resets due to inset or config changes
|
||||
public static final int HANDLE_STATE_APPLY = 1 << 1;
|
||||
|
||||
public long duration;
|
||||
public boolean userControlled;
|
||||
public @AnimationPropertyFlags int animProps = 0;
|
||||
public @AnimationFlags int animFlags = 0;
|
||||
|
||||
|
||||
@@ -105,12 +116,16 @@ public class StateAnimationConfig {
|
||||
public void copyTo(StateAnimationConfig target) {
|
||||
target.duration = duration;
|
||||
target.animFlags = animFlags;
|
||||
target.userControlled = userControlled;
|
||||
target.animProps = animProps;
|
||||
for (int i = 0; i < ANIM_TYPES_COUNT; i++) {
|
||||
target.mInterpolators[i] = mInterpolators[i];
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isUserControlled() {
|
||||
return (animProps & USER_CONTROLLED) != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the interpolator set for animId or fallback if nothing is set
|
||||
*
|
||||
|
||||
@@ -192,7 +192,7 @@ public class AllAppsSwipeController extends AbstractStateChangeTouchController {
|
||||
protected StateAnimationConfig getConfigForStates(LauncherState fromState,
|
||||
LauncherState toState) {
|
||||
StateAnimationConfig config = super.getConfigForStates(fromState, toState);
|
||||
config.userControlled = true;
|
||||
config.animProps |= StateAnimationConfig.USER_CONTROLLED;
|
||||
if (fromState == NORMAL && toState == ALL_APPS) {
|
||||
applyNormalToAllAppsAnimConfig(mLauncher, config);
|
||||
} else if (fromState == ALL_APPS && toState == NORMAL) {
|
||||
@@ -209,13 +209,13 @@ public class AllAppsSwipeController extends AbstractStateChangeTouchController {
|
||||
config.setInterpolator(ANIM_SCRIM_FADE,
|
||||
Interpolators.reverse(ALL_APPS_SCRIM_RESPONDER));
|
||||
config.setInterpolator(ANIM_ALL_APPS_FADE, FINAL_FRAME);
|
||||
if (!config.userControlled) {
|
||||
if (!config.isUserControlled()) {
|
||||
config.setInterpolator(ANIM_VERTICAL_PROGRESS, EMPHASIZED);
|
||||
}
|
||||
config.setInterpolator(ANIM_WORKSPACE_SCALE, DECELERATED_EASE);
|
||||
config.setInterpolator(ANIM_DEPTH, DECELERATED_EASE);
|
||||
} else {
|
||||
if (config.userControlled) {
|
||||
if (config.isUserControlled()) {
|
||||
config.setInterpolator(ANIM_DEPTH, Interpolators.reverse(BLUR_MANUAL));
|
||||
config.setInterpolator(ANIM_WORKSPACE_FADE,
|
||||
Interpolators.reverse(WORKSPACE_FADE_MANUAL));
|
||||
@@ -250,29 +250,32 @@ public class AllAppsSwipeController extends AbstractStateChangeTouchController {
|
||||
if (launcher.getDeviceProfile().isTablet) {
|
||||
config.setInterpolator(ANIM_ALL_APPS_FADE, INSTANT);
|
||||
config.setInterpolator(ANIM_SCRIM_FADE, ALL_APPS_SCRIM_RESPONDER);
|
||||
if (!config.userControlled) {
|
||||
if (!config.isUserControlled()) {
|
||||
config.setInterpolator(ANIM_VERTICAL_PROGRESS, EMPHASIZED);
|
||||
}
|
||||
config.setInterpolator(ANIM_WORKSPACE_SCALE, DECELERATED_EASE);
|
||||
config.setInterpolator(ANIM_DEPTH, DECELERATED_EASE);
|
||||
} else {
|
||||
config.setInterpolator(ANIM_DEPTH, config.userControlled ? BLUR_MANUAL : BLUR_ATOMIC);
|
||||
config.setInterpolator(ANIM_DEPTH,
|
||||
config.isUserControlled() ? BLUR_MANUAL : BLUR_ATOMIC);
|
||||
config.setInterpolator(ANIM_WORKSPACE_FADE,
|
||||
config.userControlled ? WORKSPACE_FADE_MANUAL : WORKSPACE_FADE_ATOMIC);
|
||||
config.isUserControlled() ? WORKSPACE_FADE_MANUAL : WORKSPACE_FADE_ATOMIC);
|
||||
config.setInterpolator(ANIM_WORKSPACE_SCALE,
|
||||
config.userControlled ? WORKSPACE_SCALE_MANUAL : WORKSPACE_SCALE_ATOMIC);
|
||||
config.isUserControlled() ? WORKSPACE_SCALE_MANUAL : WORKSPACE_SCALE_ATOMIC);
|
||||
config.setInterpolator(ANIM_HOTSEAT_FADE,
|
||||
config.userControlled ? HOTSEAT_FADE_MANUAL : HOTSEAT_FADE_ATOMIC);
|
||||
config.isUserControlled() ? HOTSEAT_FADE_MANUAL : HOTSEAT_FADE_ATOMIC);
|
||||
config.setInterpolator(ANIM_HOTSEAT_SCALE,
|
||||
config.userControlled ? HOTSEAT_SCALE_MANUAL : HOTSEAT_SCALE_ATOMIC);
|
||||
config.isUserControlled() ? HOTSEAT_SCALE_MANUAL : HOTSEAT_SCALE_ATOMIC);
|
||||
config.setInterpolator(ANIM_HOTSEAT_TRANSLATE,
|
||||
config.userControlled ? HOTSEAT_TRANSLATE_MANUAL : HOTSEAT_TRANSLATE_ATOMIC);
|
||||
config.isUserControlled()
|
||||
? HOTSEAT_TRANSLATE_MANUAL
|
||||
: HOTSEAT_TRANSLATE_ATOMIC);
|
||||
config.setInterpolator(ANIM_SCRIM_FADE,
|
||||
config.userControlled ? SCRIM_FADE_MANUAL : SCRIM_FADE_ATOMIC);
|
||||
config.isUserControlled() ? SCRIM_FADE_MANUAL : SCRIM_FADE_ATOMIC);
|
||||
config.setInterpolator(ANIM_ALL_APPS_FADE,
|
||||
config.userControlled ? ALL_APPS_FADE_MANUAL : ALL_APPS_FADE_ATOMIC);
|
||||
config.isUserControlled() ? ALL_APPS_FADE_MANUAL : ALL_APPS_FADE_ATOMIC);
|
||||
config.setInterpolator(ANIM_VERTICAL_PROGRESS,
|
||||
config.userControlled
|
||||
config.isUserControlled()
|
||||
? ALL_APPS_VERTICAL_PROGRESS_MANUAL
|
||||
: ALL_APPS_VERTICAL_PROGRESS_ATOMIC);
|
||||
}
|
||||
@@ -285,7 +288,7 @@ public class AllAppsSwipeController extends AbstractStateChangeTouchController {
|
||||
*/
|
||||
public static void applyOverviewToAllAppsAnimConfig(
|
||||
DeviceProfile deviceProfile, StateAnimationConfig config, float threshold) {
|
||||
config.userControlled = true;
|
||||
config.animProps |= StateAnimationConfig.USER_CONTROLLED;
|
||||
config.animFlags = SKIP_OVERVIEW;
|
||||
if (deviceProfile.isTablet) {
|
||||
config.setInterpolator(ANIM_ALL_APPS_FADE, INSTANT);
|
||||
|
||||
@@ -26,6 +26,8 @@ import com.android.launcher3.anim.AnimatorListeners
|
||||
import com.android.launcher3.anim.AnimatorPlaybackController
|
||||
import com.android.launcher3.anim.PendingAnimation
|
||||
import com.android.launcher3.statemanager.StatefulActivity
|
||||
import com.android.launcher3.states.StateAnimationConfig.HANDLE_STATE_APPLY
|
||||
import com.android.launcher3.states.StateAnimationConfig.USER_CONTROLLED
|
||||
import java.util.function.Consumer
|
||||
|
||||
private const val TAG = "CannedAnimCoordinator"
|
||||
@@ -107,8 +109,15 @@ class CannedAnimationCoordinator(private val activity: StatefulActivity<*>) {
|
||||
}
|
||||
// Link this to the state manager so that it auto-cancels when state changes
|
||||
recreatePending = false
|
||||
// Animator coordinator takes care of reapplying the animation due to state reset. Set the
|
||||
// flags accordingly
|
||||
animationController =
|
||||
controller.apply { activity.stateManager.setCurrentUserControlledAnimation(this) }
|
||||
controller.apply {
|
||||
activity.stateManager.setCurrentAnimation(
|
||||
this,
|
||||
USER_CONTROLLED or HANDLE_STATE_APPLY
|
||||
)
|
||||
}
|
||||
recreateAnimation(provider)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user