Loading quickstep/recents_ui_overrides/res/values/dimens.xml +4 −0 Original line number Diff line number Diff line Loading @@ -23,4 +23,8 @@ <!-- Minimum distance to swipe to trigger accessibility gesture --> <dimen name="accessibility_gesture_min_swipe_distance">80dp</dimen> <!-- Swipe up to home related --> <dimen name="swipe_up_fling_min_visible_change">18dp</dimen> <dimen name="swipe_up_y_overshoot">10dp</dimen> </resources> No newline at end of file quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java +1 −2 Original line number Diff line number Diff line Loading @@ -1077,8 +1077,7 @@ public class WindowTransformSwipeHandler<T extends BaseDraggingActivity> final View floatingView = homeAnimationFactory.getFloatingView(); final boolean isFloatingIconView = floatingView instanceof FloatingIconView; RectFSpringAnim anim = new RectFSpringAnim(startRect, targetRect); RectFSpringAnim anim = new RectFSpringAnim(startRect, targetRect, mActivity.getResources()); if (isFloatingIconView) { FloatingIconView fiv = (FloatingIconView) floatingView; anim.addAnimatorListener(fiv); Loading quickstep/recents_ui_overrides/src/com/android/quickstep/util/RectFSpringAnim.java +51 −16 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ import android.animation.Animator; import android.animation.ObjectAnimator; import android.animation.PropertyValuesHolder; import android.animation.ValueAnimator; import android.content.res.Resources; import android.graphics.PointF; import android.graphics.RectF; import android.util.FloatProperty; Loading @@ -26,6 +27,7 @@ import android.util.FloatProperty; import androidx.dynamicanimation.animation.DynamicAnimation.OnAnimationEndListener; import androidx.dynamicanimation.animation.FloatPropertyCompat; import com.android.launcher3.R; import com.android.launcher3.Utilities; import com.android.launcher3.anim.AnimationSuccessListener; import com.android.launcher3.anim.FlingSpringAnim; Loading Loading @@ -63,16 +65,16 @@ public class RectFSpringAnim { } }; private static final FloatPropertyCompat<RectFSpringAnim> RECT_CENTER_Y = new FloatPropertyCompat<RectFSpringAnim>("rectCenterYSpring") { private static final FloatPropertyCompat<RectFSpringAnim> RECT_Y = new FloatPropertyCompat<RectFSpringAnim>("rectYSpring") { @Override public float getValue(RectFSpringAnim anim) { return anim.mCurrentCenterY; return anim.mCurrentY; } @Override public void setValue(RectFSpringAnim anim, float currentCenterY) { anim.mCurrentCenterY = currentCenterY; public void setValue(RectFSpringAnim anim, float y) { anim.mCurrentY = y; anim.onUpdate(); } }; Loading @@ -98,7 +100,9 @@ public class RectFSpringAnim { private final List<Animator.AnimatorListener> mAnimatorListeners = new ArrayList<>(); private float mCurrentCenterX; private float mCurrentCenterY; private float mCurrentY; // If true, tracking the bottom of the rects, else tracking the top. private boolean mTrackingBottomY; private float mCurrentScaleProgress; private FlingSpringAnim mRectXAnim; private FlingSpringAnim mRectYAnim; Loading @@ -108,19 +112,32 @@ public class RectFSpringAnim { private boolean mRectYAnimEnded; private boolean mRectScaleAnimEnded; public RectFSpringAnim(RectF startRect, RectF targetRect) { private float mMinVisChange; private float mYOvershoot; public RectFSpringAnim(RectF startRect, RectF targetRect, Resources resources) { mStartRect = startRect; mTargetRect = targetRect; mCurrentCenterX = mStartRect.centerX(); mCurrentCenterY = mStartRect.centerY(); mTrackingBottomY = startRect.bottom < targetRect.bottom; mCurrentY = mTrackingBottomY ? mStartRect.bottom : mStartRect.top; mMinVisChange = resources.getDimensionPixelSize(R.dimen.swipe_up_fling_min_visible_change); mYOvershoot = resources.getDimensionPixelSize(R.dimen.swipe_up_y_overshoot); } public void onTargetPositionChanged() { if (mRectXAnim != null && mRectXAnim.getTargetPosition() != mTargetRect.centerX()) { mRectXAnim.updatePosition(mCurrentCenterX, mTargetRect.centerX()); } if (mRectYAnim != null && mRectYAnim.getTargetPosition() != mTargetRect.centerY()) { mRectYAnim.updatePosition(mCurrentCenterY, mTargetRect.centerY()); if (mRectYAnim != null) { if (mTrackingBottomY && mRectYAnim.getTargetPosition() != mTargetRect.bottom) { mRectYAnim.updatePosition(mCurrentY, mTargetRect.bottom); } else if (!mTrackingBottomY && mRectYAnim.getTargetPosition() != mTargetRect.top) { mRectYAnim.updatePosition(mCurrentY, mTargetRect.top); } } } Loading @@ -142,10 +159,23 @@ public class RectFSpringAnim { mRectYAnimEnded = true; maybeOnEnd(); }); mRectXAnim = new FlingSpringAnim(this, RECT_CENTER_X, mCurrentCenterX, mTargetRect.centerX(), velocityPxPerMs.x * 1000, onXEndListener); mRectYAnim = new FlingSpringAnim(this, RECT_CENTER_Y, mCurrentCenterY, mTargetRect.centerY(), velocityPxPerMs.y * 1000, onYEndListener); float startX = mCurrentCenterX; float endX = mTargetRect.centerX(); float minXValue = Math.min(startX, endX); float maxXValue = Math.max(startX, endX); mRectXAnim = new FlingSpringAnim(this, RECT_CENTER_X, startX, endX, velocityPxPerMs.x * 1000, mMinVisChange, minXValue, maxXValue, 1f, onXEndListener); float startVelocityY = velocityPxPerMs.y * 1000; // Scale the Y velocity based on the initial velocity to tune the curves. float springVelocityFactor = 0.1f + 0.9f * Math.abs(startVelocityY) / 20000.0f; float startY = mCurrentY; float endY = mTrackingBottomY ? mTargetRect.bottom : mTargetRect.top; float minYValue = Math.min(startY, endY - mYOvershoot); float maxYValue = Math.max(startY, endY); mRectYAnim = new FlingSpringAnim(this, RECT_Y, startY, endY, startVelocityY, mMinVisChange, minYValue, maxYValue, springVelocityFactor, onYEndListener); mRectScaleAnim = ObjectAnimator.ofPropertyValuesHolder(this, PropertyValuesHolder.ofFloat(RECT_SCALE_PROGRESS, 1)) Loading Loading @@ -182,8 +212,13 @@ public class RectFSpringAnim { mTargetRect.width()); float currentHeight = Utilities.mapRange(mCurrentScaleProgress, mStartRect.height(), mTargetRect.height()); mCurrentRect.set(mCurrentCenterX - currentWidth / 2, mCurrentCenterY - currentHeight / 2, mCurrentCenterX + currentWidth / 2, mCurrentCenterY + currentHeight / 2); if (mTrackingBottomY) { mCurrentRect.set(mCurrentCenterX - currentWidth / 2, mCurrentY - currentHeight, mCurrentCenterX + currentWidth / 2, mCurrentY); } else { mCurrentRect.set(mCurrentCenterX - currentWidth / 2, mCurrentY, mCurrentCenterX + currentWidth / 2, mCurrentY + currentHeight); } for (OnUpdateListener onUpdateListener : mOnUpdateListeners) { onUpdateListener.onUpdate(mCurrentRect, mCurrentScaleProgress); } Loading src/com/android/launcher3/anim/FlingSpringAnim.java +10 −8 Original line number Diff line number Diff line Loading @@ -28,8 +28,6 @@ import androidx.dynamicanimation.animation.SpringForce; public class FlingSpringAnim { private static final float FLING_FRICTION = 1.5f; // Have the spring pull towards the target if we've slowed down too much before reaching it. private static final float FLING_END_THRESHOLD_PX = 50f; private static final float SPRING_STIFFNESS = 200; private static final float SPRING_DAMPING = 0.85f; Loading @@ -39,23 +37,27 @@ public class FlingSpringAnim { private float mTargetPosition; public <K> FlingSpringAnim(K object, FloatPropertyCompat<K> property, float startPosition, float targetPosition, float startVelocity, OnAnimationEndListener onEndListener) { float targetPosition, float startVelocity, float minVisChange, float minValue, float maxValue, float springVelocityFactor, OnAnimationEndListener onEndListener) { mFlingAnim = new FlingAnimation(object, property) .setFriction(FLING_FRICTION) .setMinimumVisibleChange(FLING_END_THRESHOLD_PX) // Have the spring pull towards the target if we've slowed down too much before // reaching it. .setMinimumVisibleChange(minVisChange) .setStartVelocity(startVelocity) .setMinValue(Math.min(startPosition, targetPosition)) .setMaxValue(Math.max(startPosition, targetPosition)); .setMinValue(minValue) .setMaxValue(maxValue); mTargetPosition = targetPosition; mFlingAnim.addEndListener(((animation, canceled, value, velocity) -> { mSpringAnim = new SpringAnimation(object, property) .setStartVelocity(velocity) .setStartValue(value) .setStartVelocity(velocity * springVelocityFactor) .setSpring(new SpringForce(mTargetPosition) .setStiffness(SPRING_STIFFNESS) .setDampingRatio(SPRING_DAMPING)); mSpringAnim.addEndListener(onEndListener); mSpringAnim.start(); mSpringAnim.animateToFinalPosition(mTargetPosition); })); } Loading Loading
quickstep/recents_ui_overrides/res/values/dimens.xml +4 −0 Original line number Diff line number Diff line Loading @@ -23,4 +23,8 @@ <!-- Minimum distance to swipe to trigger accessibility gesture --> <dimen name="accessibility_gesture_min_swipe_distance">80dp</dimen> <!-- Swipe up to home related --> <dimen name="swipe_up_fling_min_visible_change">18dp</dimen> <dimen name="swipe_up_y_overshoot">10dp</dimen> </resources> No newline at end of file
quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java +1 −2 Original line number Diff line number Diff line Loading @@ -1077,8 +1077,7 @@ public class WindowTransformSwipeHandler<T extends BaseDraggingActivity> final View floatingView = homeAnimationFactory.getFloatingView(); final boolean isFloatingIconView = floatingView instanceof FloatingIconView; RectFSpringAnim anim = new RectFSpringAnim(startRect, targetRect); RectFSpringAnim anim = new RectFSpringAnim(startRect, targetRect, mActivity.getResources()); if (isFloatingIconView) { FloatingIconView fiv = (FloatingIconView) floatingView; anim.addAnimatorListener(fiv); Loading
quickstep/recents_ui_overrides/src/com/android/quickstep/util/RectFSpringAnim.java +51 −16 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ import android.animation.Animator; import android.animation.ObjectAnimator; import android.animation.PropertyValuesHolder; import android.animation.ValueAnimator; import android.content.res.Resources; import android.graphics.PointF; import android.graphics.RectF; import android.util.FloatProperty; Loading @@ -26,6 +27,7 @@ import android.util.FloatProperty; import androidx.dynamicanimation.animation.DynamicAnimation.OnAnimationEndListener; import androidx.dynamicanimation.animation.FloatPropertyCompat; import com.android.launcher3.R; import com.android.launcher3.Utilities; import com.android.launcher3.anim.AnimationSuccessListener; import com.android.launcher3.anim.FlingSpringAnim; Loading Loading @@ -63,16 +65,16 @@ public class RectFSpringAnim { } }; private static final FloatPropertyCompat<RectFSpringAnim> RECT_CENTER_Y = new FloatPropertyCompat<RectFSpringAnim>("rectCenterYSpring") { private static final FloatPropertyCompat<RectFSpringAnim> RECT_Y = new FloatPropertyCompat<RectFSpringAnim>("rectYSpring") { @Override public float getValue(RectFSpringAnim anim) { return anim.mCurrentCenterY; return anim.mCurrentY; } @Override public void setValue(RectFSpringAnim anim, float currentCenterY) { anim.mCurrentCenterY = currentCenterY; public void setValue(RectFSpringAnim anim, float y) { anim.mCurrentY = y; anim.onUpdate(); } }; Loading @@ -98,7 +100,9 @@ public class RectFSpringAnim { private final List<Animator.AnimatorListener> mAnimatorListeners = new ArrayList<>(); private float mCurrentCenterX; private float mCurrentCenterY; private float mCurrentY; // If true, tracking the bottom of the rects, else tracking the top. private boolean mTrackingBottomY; private float mCurrentScaleProgress; private FlingSpringAnim mRectXAnim; private FlingSpringAnim mRectYAnim; Loading @@ -108,19 +112,32 @@ public class RectFSpringAnim { private boolean mRectYAnimEnded; private boolean mRectScaleAnimEnded; public RectFSpringAnim(RectF startRect, RectF targetRect) { private float mMinVisChange; private float mYOvershoot; public RectFSpringAnim(RectF startRect, RectF targetRect, Resources resources) { mStartRect = startRect; mTargetRect = targetRect; mCurrentCenterX = mStartRect.centerX(); mCurrentCenterY = mStartRect.centerY(); mTrackingBottomY = startRect.bottom < targetRect.bottom; mCurrentY = mTrackingBottomY ? mStartRect.bottom : mStartRect.top; mMinVisChange = resources.getDimensionPixelSize(R.dimen.swipe_up_fling_min_visible_change); mYOvershoot = resources.getDimensionPixelSize(R.dimen.swipe_up_y_overshoot); } public void onTargetPositionChanged() { if (mRectXAnim != null && mRectXAnim.getTargetPosition() != mTargetRect.centerX()) { mRectXAnim.updatePosition(mCurrentCenterX, mTargetRect.centerX()); } if (mRectYAnim != null && mRectYAnim.getTargetPosition() != mTargetRect.centerY()) { mRectYAnim.updatePosition(mCurrentCenterY, mTargetRect.centerY()); if (mRectYAnim != null) { if (mTrackingBottomY && mRectYAnim.getTargetPosition() != mTargetRect.bottom) { mRectYAnim.updatePosition(mCurrentY, mTargetRect.bottom); } else if (!mTrackingBottomY && mRectYAnim.getTargetPosition() != mTargetRect.top) { mRectYAnim.updatePosition(mCurrentY, mTargetRect.top); } } } Loading @@ -142,10 +159,23 @@ public class RectFSpringAnim { mRectYAnimEnded = true; maybeOnEnd(); }); mRectXAnim = new FlingSpringAnim(this, RECT_CENTER_X, mCurrentCenterX, mTargetRect.centerX(), velocityPxPerMs.x * 1000, onXEndListener); mRectYAnim = new FlingSpringAnim(this, RECT_CENTER_Y, mCurrentCenterY, mTargetRect.centerY(), velocityPxPerMs.y * 1000, onYEndListener); float startX = mCurrentCenterX; float endX = mTargetRect.centerX(); float minXValue = Math.min(startX, endX); float maxXValue = Math.max(startX, endX); mRectXAnim = new FlingSpringAnim(this, RECT_CENTER_X, startX, endX, velocityPxPerMs.x * 1000, mMinVisChange, minXValue, maxXValue, 1f, onXEndListener); float startVelocityY = velocityPxPerMs.y * 1000; // Scale the Y velocity based on the initial velocity to tune the curves. float springVelocityFactor = 0.1f + 0.9f * Math.abs(startVelocityY) / 20000.0f; float startY = mCurrentY; float endY = mTrackingBottomY ? mTargetRect.bottom : mTargetRect.top; float minYValue = Math.min(startY, endY - mYOvershoot); float maxYValue = Math.max(startY, endY); mRectYAnim = new FlingSpringAnim(this, RECT_Y, startY, endY, startVelocityY, mMinVisChange, minYValue, maxYValue, springVelocityFactor, onYEndListener); mRectScaleAnim = ObjectAnimator.ofPropertyValuesHolder(this, PropertyValuesHolder.ofFloat(RECT_SCALE_PROGRESS, 1)) Loading Loading @@ -182,8 +212,13 @@ public class RectFSpringAnim { mTargetRect.width()); float currentHeight = Utilities.mapRange(mCurrentScaleProgress, mStartRect.height(), mTargetRect.height()); mCurrentRect.set(mCurrentCenterX - currentWidth / 2, mCurrentCenterY - currentHeight / 2, mCurrentCenterX + currentWidth / 2, mCurrentCenterY + currentHeight / 2); if (mTrackingBottomY) { mCurrentRect.set(mCurrentCenterX - currentWidth / 2, mCurrentY - currentHeight, mCurrentCenterX + currentWidth / 2, mCurrentY); } else { mCurrentRect.set(mCurrentCenterX - currentWidth / 2, mCurrentY, mCurrentCenterX + currentWidth / 2, mCurrentY + currentHeight); } for (OnUpdateListener onUpdateListener : mOnUpdateListeners) { onUpdateListener.onUpdate(mCurrentRect, mCurrentScaleProgress); } Loading
src/com/android/launcher3/anim/FlingSpringAnim.java +10 −8 Original line number Diff line number Diff line Loading @@ -28,8 +28,6 @@ import androidx.dynamicanimation.animation.SpringForce; public class FlingSpringAnim { private static final float FLING_FRICTION = 1.5f; // Have the spring pull towards the target if we've slowed down too much before reaching it. private static final float FLING_END_THRESHOLD_PX = 50f; private static final float SPRING_STIFFNESS = 200; private static final float SPRING_DAMPING = 0.85f; Loading @@ -39,23 +37,27 @@ public class FlingSpringAnim { private float mTargetPosition; public <K> FlingSpringAnim(K object, FloatPropertyCompat<K> property, float startPosition, float targetPosition, float startVelocity, OnAnimationEndListener onEndListener) { float targetPosition, float startVelocity, float minVisChange, float minValue, float maxValue, float springVelocityFactor, OnAnimationEndListener onEndListener) { mFlingAnim = new FlingAnimation(object, property) .setFriction(FLING_FRICTION) .setMinimumVisibleChange(FLING_END_THRESHOLD_PX) // Have the spring pull towards the target if we've slowed down too much before // reaching it. .setMinimumVisibleChange(minVisChange) .setStartVelocity(startVelocity) .setMinValue(Math.min(startPosition, targetPosition)) .setMaxValue(Math.max(startPosition, targetPosition)); .setMinValue(minValue) .setMaxValue(maxValue); mTargetPosition = targetPosition; mFlingAnim.addEndListener(((animation, canceled, value, velocity) -> { mSpringAnim = new SpringAnimation(object, property) .setStartVelocity(velocity) .setStartValue(value) .setStartVelocity(velocity * springVelocityFactor) .setSpring(new SpringForce(mTargetPosition) .setStiffness(SPRING_STIFFNESS) .setDampingRatio(SPRING_DAMPING)); mSpringAnim.addEndListener(onEndListener); mSpringAnim.start(); mSpringAnim.animateToFinalPosition(mTargetPosition); })); } Loading