Merge "Swipe up to home animation changes." into ub-launcher3-qt-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
06892dcfab
@@ -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>
|
||||
+1
-2
@@ -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);
|
||||
|
||||
+51
-16
@@ -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;
|
||||
@@ -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;
|
||||
@@ -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();
|
||||
}
|
||||
};
|
||||
@@ -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;
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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))
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}));
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user