Add springs for recents dismiss animations.

Bug: 111698021
Change-Id: If518ba5946ea6fada67f549f2f29e1ab1c89969d
This commit is contained in:
Jon Miranda 2019-01-29 11:14:38 -08:00
parent 9752705e92
commit 86f6c449a7
6 changed files with 79 additions and 31 deletions

View File

@ -18,6 +18,7 @@ package com.android.launcher3.uioverrides;
import static com.android.launcher3.AbstractFloatingView.TYPE_ACCESSIBLE;
import static com.android.launcher3.Utilities.SINGLE_FRAME_MS;
import static com.android.launcher3.anim.Interpolators.scrollInterpolatorForVelocity;
import static com.android.launcher3.config.FeatureFlags.QUICKSTEP_SPRINGS;
import static com.android.launcher3.config.FeatureFlags.ENABLE_QUICKSTEP_LIVE_TILE;
import android.animation.Animator;
@ -281,6 +282,9 @@ public abstract class TaskViewTouchController<T extends BaseDraggingActivity>
}
});
}
if (QUICKSTEP_SPRINGS.get()) {
mCurrentAnimation.dispatchOnStartWithVelocity(goingToEnd ? 1f : 0f, velocity);
}
anim.start();
}

View File

@ -23,7 +23,8 @@ import static com.android.launcher3.LauncherState.BACKGROUND_APP;
import static com.android.launcher3.LauncherState.FAST_OVERVIEW;
import static com.android.launcher3.LauncherState.NORMAL;
import static com.android.launcher3.LauncherState.OVERVIEW;
import static com.android.launcher3.allapps.AllAppsTransitionController.ALL_APPS_PROGRESS_SPRING;
import static com.android.launcher3.allapps.AllAppsTransitionController.SPRING_DAMPING_RATIO;
import static com.android.launcher3.allapps.AllAppsTransitionController.SPRING_STIFFNESS;
import static com.android.launcher3.anim.Interpolators.LINEAR;
import static com.android.launcher3.states.RotationHelper.REQUEST_LOCK;
import static com.android.quickstep.TouchConsumer.INTERACTION_NORMAL;
@ -394,9 +395,9 @@ public interface ActivityControlHelper<T extends BaseDraggingActivity> {
}
private Animator createShelfAnim(Launcher activity, float ... progressValues) {
Animator shiftAnim = new SpringObjectAnimator(activity.getAllAppsController(),
ALL_APPS_PROGRESS_SPRING, "allAppsSpringFromACH",
activity.getAllAppsController().getShiftRange(), progressValues);
Animator shiftAnim = new SpringObjectAnimator<>(activity.getAllAppsController(),
"allAppsSpringFromACH", activity.getAllAppsController().getShiftRange(),
SPRING_DAMPING_RATIO, SPRING_STIFFNESS, progressValues);
shiftAnim.setInterpolator(LINEAR);
return shiftAnim;
}

View File

@ -22,6 +22,7 @@ import static com.android.launcher3.anim.Interpolators.ACCEL;
import static com.android.launcher3.anim.Interpolators.ACCEL_2;
import static com.android.launcher3.anim.Interpolators.FAST_OUT_SLOW_IN;
import static com.android.launcher3.anim.Interpolators.LINEAR;
import static com.android.launcher3.config.FeatureFlags.QUICKSTEP_SPRINGS;
import static com.android.launcher3.config.FeatureFlags.ENABLE_QUICKSTEP_LIVE_TILE;
import static com.android.launcher3.uioverrides.TaskViewTouchController.SUCCESS_TRANSITION_PROGRESS;
import static com.android.quickstep.util.ClipAnimationHelper.TransformParams;
@ -66,16 +67,19 @@ import android.view.accessibility.AccessibilityNodeInfo;
import android.widget.ListView;
import androidx.annotation.Nullable;
import androidx.dynamicanimation.animation.SpringForce;
import com.android.launcher3.BaseActivity;
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.Insettable;
import com.android.launcher3.InvariantDeviceProfile;
import com.android.launcher3.LauncherAnimUtils.ViewProgressProperty;
import com.android.launcher3.PagedView;
import com.android.launcher3.R;
import com.android.launcher3.Utilities;
import com.android.launcher3.anim.AnimatorPlaybackController;
import com.android.launcher3.anim.PropertyListBuilder;
import com.android.launcher3.anim.SpringObjectAnimator;
import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Direction;
import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Touch;
@ -113,6 +117,10 @@ public abstract class RecentsView<T extends BaseActivity> extends PagedView impl
private static final String TAG = RecentsView.class.getSimpleName();
public static final float SPRING_MIN_VISIBLE_CHANGE = 0.001f;
public static final float SPRING_DAMPING_RATIO = SpringForce.DAMPING_RATIO_MEDIUM_BOUNCY;
public static final float SPRING_STIFFNESS = SpringForce.STIFFNESS_LOW;
public static final FloatProperty<RecentsView> CONTENT_ALPHA =
new FloatProperty<RecentsView>("contentAlpha") {
@Override
@ -941,8 +949,15 @@ public abstract class RecentsView<T extends BaseActivity> extends PagedView impl
private void addDismissedTaskAnimations(View taskView, AnimatorSet anim, long duration) {
addAnim(ObjectAnimator.ofFloat(taskView, ALPHA, 0), duration, ACCEL_2, anim);
addAnim(ObjectAnimator.ofFloat(taskView, TRANSLATION_Y, -taskView.getHeight()),
duration, LINEAR, anim);
if (QUICKSTEP_SPRINGS.get() && taskView instanceof TaskView)
addAnim(new SpringObjectAnimator<>(new ViewProgressProperty(taskView,
View.TRANSLATION_Y), "taskViewTransY", SPRING_MIN_VISIBLE_CHANGE,
SPRING_DAMPING_RATIO, SPRING_STIFFNESS, 0, -taskView.getHeight()),
duration, LINEAR, anim);
else {
addAnim(ObjectAnimator.ofFloat(taskView, TRANSLATION_Y, -taskView.getHeight()),
duration, LINEAR, anim);
}
}
private void removeTask(Task task, int index, PendingAnimation.OnEndListener onEndListener,
@ -1012,8 +1027,16 @@ public abstract class RecentsView<T extends BaseActivity> extends PagedView impl
}
int scrollDiff = newScroll[i] - oldScroll[i] + offset;
if (scrollDiff != 0) {
addAnim(ObjectAnimator.ofFloat(child, TRANSLATION_X, scrollDiff),
duration, ACCEL, anim);
if (QUICKSTEP_SPRINGS.get() && child instanceof TaskView) {
addAnim(new SpringObjectAnimator<>(
new ViewProgressProperty(child, View.TRANSLATION_X),
"taskViewTransX", SPRING_MIN_VISIBLE_CHANGE, SPRING_DAMPING_RATIO,
SPRING_STIFFNESS, 0, scrollDiff), duration, ACCEL, anim);
} else {
addAnim(ObjectAnimator.ofFloat(child, TRANSLATION_X, scrollDiff), duration,
ACCEL, anim);
}
needsCurveUpdates = true;
}
}
@ -1094,7 +1117,7 @@ public abstract class RecentsView<T extends BaseActivity> extends PagedView impl
return pendingAnimation;
}
private static void addAnim(ObjectAnimator anim, long duration,
private static void addAnim(Animator anim, long duration,
TimeInterpolator interpolator, AnimatorSet set) {
anim.setDuration(duration).setInterpolator(interpolator);
set.play(anim);

View File

@ -91,4 +91,24 @@ public class LauncherAnimUtils {
lp.height = height;
}
};
public static class ViewProgressProperty implements ProgressInterface {
View mView;
Property<View, Float> mProperty;
public ViewProgressProperty(View view, Property<View, Float> property) {
mView = view;
mProperty = property;
}
@Override
public void setProgress(float progress) {
mProperty.set(mView, progress);
}
@Override
public float getProgress() {
return mProperty.get(mView);
}
}
}

View File

@ -47,6 +47,9 @@ import androidx.dynamicanimation.animation.FloatPropertyCompat;
public class AllAppsTransitionController implements StateHandler, OnDeviceProfileChangeListener,
ProgressInterface {
public static final float SPRING_DAMPING_RATIO = 0.9f;
public static final float SPRING_STIFFNESS = 600f;
public static final Property<AllAppsTransitionController, Float> ALL_APPS_PROGRESS =
new Property<AllAppsTransitionController, Float>(Float.class, "allAppsProgress") {
@ -61,19 +64,6 @@ public class AllAppsTransitionController implements StateHandler, OnDeviceProfil
}
};
public static final FloatPropertyCompat<AllAppsTransitionController> ALL_APPS_PROGRESS_SPRING
= new FloatPropertyCompat<AllAppsTransitionController>("allAppsProgressSpring") {
@Override
public float getValue(AllAppsTransitionController controller) {
return controller.mProgress;
}
@Override
public void setValue(AllAppsTransitionController controller, float progress) {
controller.setProgress(progress);
}
};
private AllAppsContainerView mAppsView;
private ScrimView mScrimView;
@ -191,8 +181,8 @@ public class AllAppsTransitionController implements StateHandler, OnDeviceProfil
Interpolator interpolator = config.userControlled ? LINEAR : toState == OVERVIEW
? builder.getInterpolator(ANIM_OVERVIEW_SCALE, FAST_OUT_SLOW_IN)
: FAST_OUT_SLOW_IN;
Animator anim = new SpringObjectAnimator<>(this, ALL_APPS_PROGRESS_SPRING,
"allAppsSpringFromAATC", 1f / mShiftRange, mProgress, targetProgress);
Animator anim = new SpringObjectAnimator<>(this, "allAppsSpringFromAATC", 1f / mShiftRange,
SPRING_DAMPING_RATIO, SPRING_STIFFNESS, mProgress, targetProgress);
anim.setDuration(config.duration);
anim.setInterpolator(builder.getInterpolator(ANIM_VERTICAL_PROGRESS, interpolator));
anim.addListener(getProgressAnimatorListener());

View File

@ -55,17 +55,27 @@ public class SpringObjectAnimator<T extends ProgressInterface> extends ValueAnim
private boolean mAnimatorEnded = false;
private boolean mEnded = false;
private static final float SPRING_DAMPING_RATIO = 0.9f;
private static final float SPRING_STIFFNESS = 600f;
private static final FloatPropertyCompat<ProgressInterface> sFloatProperty =
new FloatPropertyCompat<ProgressInterface>("springObjectAnimator") {
@Override
public float getValue(ProgressInterface object) {
return object.getProgress();
}
public SpringObjectAnimator(T object, FloatPropertyCompat<T> floatProperty,
String name, float minimumVisibleChange, float... values) {
@Override
public void setValue(ProgressInterface object, float progress) {
object.setProgress(progress);
}
};
public SpringObjectAnimator(T object, String name, float minimumVisibleChange, float damping,
float stiffness, float... values) {
mObject = object;
mSpring = new SpringAnimation(object, floatProperty);
mSpring = new SpringAnimation(object, sFloatProperty);
mSpring.setMinimumVisibleChange(minimumVisibleChange);
mSpring.setSpring(new SpringForce(0)
.setDampingRatio(SPRING_DAMPING_RATIO)
.setStiffness(SPRING_STIFFNESS));
.setDampingRatio(damping)
.setStiffness(stiffness));
mSpring.setStartVelocity(0.01f);
mProperty = new SpringProperty<T>(name, mSpring);
mObjectAnimator = ObjectAnimator.ofFloat(object, mProperty, values);