mirror of
https://github.com/LawnchairLauncher/lawnchair.git
synced 2026-02-19 10:48:19 +00:00
Remove Overview atomic animation support
- Remove PLAY_ATOMIC_OVERVIEW_SCALE and PLAY_ATOMIC_OVERVIEW_PEEK - Remove complicated parallel atomic animation support from AbstractStateChangeTouchController and subclasses - Remove some code related to going between Overview <-> AllApps Test: Swipe between states in all 3 navigation modes Bug: 175137718 Change-Id: Ice314d46946c3a983cdc6ccf1a67effb5da9156e
This commit is contained in:
@@ -27,30 +27,20 @@ import static com.android.launcher3.logging.StatsLogManager.LAUNCHER_STATE_HOME;
|
||||
import static com.android.launcher3.logging.StatsLogManager.LAUNCHER_STATE_OVERVIEW;
|
||||
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_UNKNOWN_SWIPEDOWN;
|
||||
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_UNKNOWN_SWIPEUP;
|
||||
import static com.android.launcher3.states.StateAnimationConfig.ANIM_ALL_COMPONENTS;
|
||||
import static com.android.launcher3.states.StateAnimationConfig.PLAY_ATOMIC_OVERVIEW_SCALE;
|
||||
import static com.android.launcher3.states.StateAnimationConfig.PLAY_NON_ATOMIC;
|
||||
import static com.android.launcher3.util.DisplayController.getSingleFrameMs;
|
||||
|
||||
import android.animation.Animator;
|
||||
import android.animation.Animator.AnimatorListener;
|
||||
import android.animation.AnimatorListenerAdapter;
|
||||
import android.animation.AnimatorSet;
|
||||
import android.animation.ValueAnimator;
|
||||
import android.os.SystemClock;
|
||||
import android.view.HapticFeedbackConstants;
|
||||
import android.view.MotionEvent;
|
||||
|
||||
import com.android.launcher3.Launcher;
|
||||
import com.android.launcher3.LauncherAnimUtils;
|
||||
import com.android.launcher3.LauncherState;
|
||||
import com.android.launcher3.Utilities;
|
||||
import com.android.launcher3.anim.AnimationSuccessListener;
|
||||
import com.android.launcher3.anim.AnimatorPlaybackController;
|
||||
import com.android.launcher3.logger.LauncherAtom;
|
||||
import com.android.launcher3.logging.StatsLogManager;
|
||||
import com.android.launcher3.states.StateAnimationConfig;
|
||||
import com.android.launcher3.states.StateAnimationConfig.AnimationFlags;
|
||||
import com.android.launcher3.util.FlingBlockCheck;
|
||||
import com.android.launcher3.util.TouchController;
|
||||
|
||||
@@ -60,13 +50,6 @@ import com.android.launcher3.util.TouchController;
|
||||
public abstract class AbstractStateChangeTouchController
|
||||
implements TouchController, SingleAxisSwipeDetector.Listener {
|
||||
|
||||
/**
|
||||
* Play an atomic recents animation when the progress from NORMAL to OVERVIEW reaches this.
|
||||
* TODO: Remove the atomic animation altogether and just go to OVERVIEW directly (b/175137718).
|
||||
*/
|
||||
public static final float ATOMIC_OVERVIEW_ANIM_THRESHOLD = 1f;
|
||||
protected final long ATOMIC_DURATION = getAtomicDuration();
|
||||
|
||||
protected final Launcher mLauncher;
|
||||
protected final SingleAxisSwipeDetector mDetector;
|
||||
protected final SingleAxisSwipeDetector.Direction mSwipeDirection;
|
||||
@@ -89,23 +72,7 @@ public abstract class AbstractStateChangeTouchController
|
||||
private float mProgressMultiplier;
|
||||
private float mDisplacementShift;
|
||||
private boolean mCanBlockFling;
|
||||
private FlingBlockCheck mFlingBlockCheck = new FlingBlockCheck();
|
||||
|
||||
protected AnimatorSet mAtomicAnim;
|
||||
// True if we want to resume playing atomic components when mAtomicAnim completes.
|
||||
private boolean mScheduleResumeAtomicComponent;
|
||||
private AutoPlayAtomicAnimationInfo mAtomicAnimAutoPlayInfo;
|
||||
|
||||
private boolean mPassedOverviewAtomicThreshold;
|
||||
// mAtomicAnim plays the atomic components of the state animations when we pass the threshold.
|
||||
// However, if we reinit to transition to a new state (e.g. OVERVIEW -> ALL_APPS) before the
|
||||
// atomic animation finishes, we only control the non-atomic components so that we don't
|
||||
// interfere with the atomic animation. When the atomic animation ends, we start controlling
|
||||
// the atomic components as well, using this controller.
|
||||
private AnimatorPlaybackController mAtomicComponentsController;
|
||||
private LauncherState mAtomicComponentsTargetState = NORMAL;
|
||||
|
||||
private float mAtomicComponentsStartProgress;
|
||||
private final FlingBlockCheck mFlingBlockCheck = new FlingBlockCheck();
|
||||
|
||||
public AbstractStateChangeTouchController(Launcher l, SingleAxisSwipeDetector.Direction dir) {
|
||||
mLauncher = l;
|
||||
@@ -113,10 +80,6 @@ public abstract class AbstractStateChangeTouchController
|
||||
mSwipeDirection = dir;
|
||||
}
|
||||
|
||||
protected long getAtomicDuration() {
|
||||
return 200;
|
||||
}
|
||||
|
||||
protected abstract boolean canInterceptTouch(MotionEvent ev);
|
||||
|
||||
@Override
|
||||
@@ -182,7 +145,7 @@ public abstract class AbstractStateChangeTouchController
|
||||
protected abstract LauncherState getTargetState(LauncherState fromState,
|
||||
boolean isDragTowardPositive);
|
||||
|
||||
protected abstract float initCurrentAnimation(@AnimationFlags int animComponents);
|
||||
protected abstract float initCurrentAnimation();
|
||||
|
||||
private boolean reinitCurrentAnimation(boolean reachedToState, boolean isDragTowardPositive) {
|
||||
LauncherState newFromState = mFromState == null ? mLauncher.getStateManager().getState()
|
||||
@@ -199,28 +162,10 @@ public abstract class AbstractStateChangeTouchController
|
||||
mToState = newToState;
|
||||
|
||||
mStartProgress = 0;
|
||||
mPassedOverviewAtomicThreshold = false;
|
||||
if (mCurrentAnimation != null) {
|
||||
mCurrentAnimation.getTarget().removeListener(mClearStateOnCancelListener);
|
||||
}
|
||||
int animComponents = goingBetweenNormalAndOverview(mFromState, mToState)
|
||||
? PLAY_NON_ATOMIC : ANIM_ALL_COMPONENTS;
|
||||
mScheduleResumeAtomicComponent = false;
|
||||
if (mAtomicAnim != null) {
|
||||
animComponents = PLAY_NON_ATOMIC;
|
||||
// Control the non-atomic components until the atomic animation finishes, then control
|
||||
// the atomic components as well.
|
||||
mScheduleResumeAtomicComponent = true;
|
||||
}
|
||||
if (goingBetweenNormalAndOverview(mFromState, mToState)
|
||||
|| mAtomicComponentsTargetState != mToState) {
|
||||
cancelAtomicComponentsController();
|
||||
}
|
||||
|
||||
if (mAtomicComponentsController != null) {
|
||||
animComponents &= ~PLAY_ATOMIC_OVERVIEW_SCALE;
|
||||
}
|
||||
mProgressMultiplier = initCurrentAnimation(animComponents);
|
||||
mProgressMultiplier = initCurrentAnimation();
|
||||
mCurrentAnimation.dispatchOnStart();
|
||||
return true;
|
||||
}
|
||||
@@ -231,13 +176,6 @@ public abstract class AbstractStateChangeTouchController
|
||||
protected void onReachedFinalState(LauncherState newToState) {
|
||||
}
|
||||
|
||||
protected boolean goingBetweenNormalAndOverview(LauncherState fromState,
|
||||
LauncherState toState) {
|
||||
return (fromState == NORMAL || fromState == OVERVIEW)
|
||||
&& (toState == NORMAL || toState == OVERVIEW)
|
||||
&& mGoingBetweenStates;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDragStart(boolean start, float startDisplacement) {
|
||||
mStartState = mLauncher.getStateManager().getState();
|
||||
@@ -252,11 +190,6 @@ public abstract class AbstractStateChangeTouchController
|
||||
} else {
|
||||
mCurrentAnimation.pause();
|
||||
mStartProgress = mCurrentAnimation.getProgressFraction();
|
||||
|
||||
mAtomicAnimAutoPlayInfo = null;
|
||||
if (mAtomicComponentsController != null) {
|
||||
mAtomicComponentsController.pause();
|
||||
}
|
||||
}
|
||||
mCanBlockFling = mFromState == NORMAL;
|
||||
mFlingBlockCheck.unblockFling();
|
||||
@@ -310,69 +243,6 @@ public abstract class AbstractStateChangeTouchController
|
||||
return;
|
||||
}
|
||||
mCurrentAnimation.setPlayFraction(fraction);
|
||||
if (mAtomicComponentsController != null) {
|
||||
// Make sure we don't divide by 0, and have at least a small runway.
|
||||
float start = Math.min(mAtomicComponentsStartProgress, 0.9f);
|
||||
mAtomicComponentsController.setPlayFraction((fraction - start) / (1 - start));
|
||||
}
|
||||
maybeUpdateAtomicAnim(mFromState, mToState, fraction);
|
||||
}
|
||||
|
||||
/**
|
||||
* When going between normal and overview states, see if we passed the overview threshold and
|
||||
* play the appropriate atomic animation if so.
|
||||
*/
|
||||
private void maybeUpdateAtomicAnim(LauncherState fromState, LauncherState toState,
|
||||
float progress) {
|
||||
if (!goingBetweenNormalAndOverview(fromState, toState)) {
|
||||
return;
|
||||
}
|
||||
boolean passedThreshold = progress >= ATOMIC_OVERVIEW_ANIM_THRESHOLD;
|
||||
if (passedThreshold != mPassedOverviewAtomicThreshold) {
|
||||
LauncherState atomicFromState = passedThreshold ? fromState: toState;
|
||||
LauncherState atomicToState = passedThreshold ? toState : fromState;
|
||||
mPassedOverviewAtomicThreshold = passedThreshold;
|
||||
if (mAtomicAnim != null) {
|
||||
mAtomicAnim.cancel();
|
||||
}
|
||||
mAtomicAnim = createAtomicAnimForState(atomicFromState, atomicToState, ATOMIC_DURATION);
|
||||
mAtomicAnim.addListener(new AnimationSuccessListener() {
|
||||
@Override
|
||||
public void onAnimationEnd(Animator animation) {
|
||||
super.onAnimationEnd(animation);
|
||||
mAtomicAnim = null;
|
||||
mScheduleResumeAtomicComponent = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAnimationSuccess(Animator animator) {
|
||||
if (!mScheduleResumeAtomicComponent) {
|
||||
return;
|
||||
}
|
||||
cancelAtomicComponentsController();
|
||||
|
||||
if (mCurrentAnimation != null) {
|
||||
mAtomicComponentsStartProgress = mCurrentAnimation.getProgressFraction();
|
||||
long duration = (long) (getShiftRange() * 2);
|
||||
mAtomicComponentsController = AnimatorPlaybackController.wrap(
|
||||
createAtomicAnimForState(mFromState, mToState, duration), duration);
|
||||
mAtomicComponentsController.dispatchOnStart();
|
||||
mAtomicComponentsTargetState = mToState;
|
||||
maybeAutoPlayAtomicComponentsAnim();
|
||||
}
|
||||
}
|
||||
});
|
||||
mAtomicAnim.start();
|
||||
mLauncher.getDragLayer().performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY);
|
||||
}
|
||||
}
|
||||
|
||||
private AnimatorSet createAtomicAnimForState(LauncherState fromState, LauncherState targetState,
|
||||
long duration) {
|
||||
StateAnimationConfig config = getConfigForStates(fromState, targetState);
|
||||
config.animFlags = PLAY_ATOMIC_OVERVIEW_SCALE;
|
||||
config.duration = duration;
|
||||
return mLauncher.getStateManager().createAtomicAnimation(fromState, targetState, config);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -451,59 +321,12 @@ public abstract class AbstractStateChangeTouchController
|
||||
mCurrentAnimation.setEndAction(() -> onSwipeInteractionCompleted(targetState));
|
||||
ValueAnimator anim = mCurrentAnimation.getAnimationPlayer();
|
||||
anim.setFloatValues(startProgress, endProgress);
|
||||
maybeUpdateAtomicAnim(mFromState, targetState, targetState == mToState ? 1f : 0f);
|
||||
updateSwipeCompleteAnimation(anim, Math.max(duration, getRemainingAtomicDuration()),
|
||||
targetState, velocity, fling);
|
||||
updateSwipeCompleteAnimation(anim, duration, targetState, velocity, fling);
|
||||
mCurrentAnimation.dispatchOnStart();
|
||||
if (fling && targetState == LauncherState.ALL_APPS && !UNSTABLE_SPRINGS.get()) {
|
||||
mLauncher.getAppsView().addSpringFromFlingUpdateListener(anim, velocity);
|
||||
}
|
||||
anim.start();
|
||||
mAtomicAnimAutoPlayInfo = new AutoPlayAtomicAnimationInfo(endProgress, anim.getDuration());
|
||||
maybeAutoPlayAtomicComponentsAnim();
|
||||
}
|
||||
|
||||
/**
|
||||
* Animates the atomic components from the current progress to the final progress.
|
||||
*
|
||||
* Note that this only applies when we are controlling the atomic components separately from
|
||||
* the non-atomic components, which only happens if we reinit before the atomic animation
|
||||
* finishes.
|
||||
*/
|
||||
private void maybeAutoPlayAtomicComponentsAnim() {
|
||||
if (mAtomicComponentsController == null || mAtomicAnimAutoPlayInfo == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
final AnimatorPlaybackController controller = mAtomicComponentsController;
|
||||
ValueAnimator atomicAnim = controller.getAnimationPlayer();
|
||||
atomicAnim.setFloatValues(controller.getProgressFraction(),
|
||||
mAtomicAnimAutoPlayInfo.toProgress);
|
||||
long duration = mAtomicAnimAutoPlayInfo.endTime - SystemClock.elapsedRealtime();
|
||||
mAtomicAnimAutoPlayInfo = null;
|
||||
if (duration <= 0) {
|
||||
atomicAnim.start();
|
||||
atomicAnim.end();
|
||||
mAtomicComponentsController = null;
|
||||
} else {
|
||||
atomicAnim.setDuration(duration);
|
||||
atomicAnim.addListener(new AnimatorListenerAdapter() {
|
||||
@Override
|
||||
public void onAnimationEnd(Animator animation) {
|
||||
if (mAtomicComponentsController == controller) {
|
||||
mAtomicComponentsController = null;
|
||||
}
|
||||
}
|
||||
});
|
||||
atomicAnim.start();
|
||||
}
|
||||
}
|
||||
|
||||
private long getRemainingAtomicDuration() {
|
||||
if (mAtomicAnim == null) {
|
||||
return 0;
|
||||
}
|
||||
return mAtomicAnim.getTotalDuration() - mAtomicAnim.getCurrentPlayTime();
|
||||
}
|
||||
|
||||
protected void updateSwipeCompleteAnimation(ValueAnimator animator, long expectedDuration,
|
||||
@@ -513,10 +336,6 @@ public abstract class AbstractStateChangeTouchController
|
||||
}
|
||||
|
||||
protected void onSwipeInteractionCompleted(LauncherState targetState) {
|
||||
if (mAtomicComponentsController != null) {
|
||||
mAtomicComponentsController.getAnimationPlayer().end();
|
||||
mAtomicComponentsController = null;
|
||||
}
|
||||
onReachedFinalState(mToState);
|
||||
clearState();
|
||||
boolean shouldGoToTargetState = mGoingBetweenStates || (mToState != targetState);
|
||||
@@ -556,37 +375,12 @@ public abstract class AbstractStateChangeTouchController
|
||||
|
||||
protected void clearState() {
|
||||
cancelAnimationControllers();
|
||||
if (mAtomicAnim != null) {
|
||||
mAtomicAnim.cancel();
|
||||
mAtomicAnim = null;
|
||||
}
|
||||
mGoingBetweenStates = true;
|
||||
mScheduleResumeAtomicComponent = false;
|
||||
mDetector.finishedScrolling();
|
||||
mDetector.setDetectableScrollConditions(0, false);
|
||||
}
|
||||
|
||||
private void cancelAnimationControllers() {
|
||||
mCurrentAnimation = null;
|
||||
cancelAtomicComponentsController();
|
||||
}
|
||||
|
||||
private void cancelAtomicComponentsController() {
|
||||
if (mAtomicComponentsController != null) {
|
||||
mAtomicComponentsController.getAnimationPlayer().cancel();
|
||||
mAtomicComponentsController = null;
|
||||
}
|
||||
mAtomicAnimAutoPlayInfo = null;
|
||||
}
|
||||
|
||||
private static class AutoPlayAtomicAnimationInfo {
|
||||
|
||||
public final float toProgress;
|
||||
public final long endTime;
|
||||
|
||||
AutoPlayAtomicAnimationInfo(float toProgress, long duration) {
|
||||
this.toProgress = toProgress;
|
||||
this.endTime = duration + SystemClock.elapsedRealtime();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user