summaryrefslogtreecommitdiffstats
path: root/src/com/android/launcher3/anim/SpringAnimationHandler.java
diff options
context:
space:
mode:
authorJon Miranda <jonmiranda@google.com>2017-06-06 15:41:21 -0700
committerJon Miranda <jonmiranda@google.com>2017-06-07 15:45:45 -0700
commit5c83e7cdc5f4d0406a5e564971871e1f694fddfc (patch)
tree0fe534bce8cd61a377cd7f14ec7325d3f85cdab1 /src/com/android/launcher3/anim/SpringAnimationHandler.java
parent3a5b835297cd2687cb66f9c9a57ca963b61ca9be (diff)
downloadandroid_packages_apps_Trebuchet-5c83e7cdc5f4d0406a5e564971871e1f694fddfc.tar.gz
android_packages_apps_Trebuchet-5c83e7cdc5f4d0406a5e564971871e1f694fddfc.tar.bz2
android_packages_apps_Trebuchet-5c83e7cdc5f4d0406a5e564971871e1f694fddfc.zip
Refactor and generalize SpringAnimationHandler.
SpringAnimationHandler is only responsible for motion tracking and updating the list of springs it is handling. Spring initialization and updates are handled by the AnimationFactory interface. This is done in preparation for future CLs where SpringAnimationHandler will be used in more cases. Bug: 38349031 Change-Id: I5ebce710cc05e4e88b708ceea5d2cfefbd0eb3d0
Diffstat (limited to 'src/com/android/launcher3/anim/SpringAnimationHandler.java')
-rw-r--r--src/com/android/launcher3/anim/SpringAnimationHandler.java176
1 files changed, 69 insertions, 107 deletions
diff --git a/src/com/android/launcher3/anim/SpringAnimationHandler.java b/src/com/android/launcher3/anim/SpringAnimationHandler.java
index 6a5e3514a..038f82682 100644
--- a/src/com/android/launcher3/anim/SpringAnimationHandler.java
+++ b/src/com/android/launcher3/anim/SpringAnimationHandler.java
@@ -15,7 +15,7 @@
*/
package com.android.launcher3.anim;
-import android.support.animation.DynamicAnimation;
+import android.support.animation.FloatPropertyCompat;
import android.support.animation.SpringAnimation;
import android.support.animation.SpringForce;
import android.support.annotation.IntDef;
@@ -24,8 +24,7 @@ import android.view.MotionEvent;
import android.view.VelocityTracker;
import android.view.View;
-import com.android.launcher3.Utilities;
-import com.android.launcher3.allapps.AlphabeticalAppsList;
+import com.android.launcher3.R;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@@ -35,77 +34,67 @@ import java.util.ArrayList;
* Handler class that manages springs for a set of views that should all move based on the same
* {@link MotionEvent}s.
*
- * Supports using physics for X or Y translations.
+ * Supports setting either X or Y velocity on the list of springs added to this handler.
*/
-public class SpringAnimationHandler {
+public class SpringAnimationHandler<T> {
private static final String TAG = "SpringAnimationHandler";
private static final boolean DEBUG = false;
- private static final float DEFAULT_MAX_VALUE = 100;
- private static final float DEFAULT_MIN_VALUE = -DEFAULT_MAX_VALUE;
-
- private static final float SPRING_DAMPING_RATIO = 0.55f;
- private static final float MIN_SPRING_STIFFNESS = 580f;
- private static final float MAX_SPRING_STIFFNESS = 900f;
+ private static final float VELOCITY_DAMPING_FACTOR = 0.175f;
@Retention(RetentionPolicy.SOURCE)
@IntDef({Y_DIRECTION, X_DIRECTION})
public @interface Direction {}
public static final int Y_DIRECTION = 0;
public static final int X_DIRECTION = 1;
- private int mDirection;
+ private int mVelocityDirection;
private VelocityTracker mVelocityTracker;
private float mCurrentVelocity = 0;
private boolean mShouldComputeVelocity = false;
+ private AnimationFactory<T> mAnimationFactory;
+
private ArrayList<SpringAnimation> mAnimations = new ArrayList<>();
- public SpringAnimationHandler(@Direction int direction) {
- mDirection = direction;
- mVelocityTracker = VelocityTracker.obtain();
+ /**
+ * @param direction Either {@link #X_DIRECTION} or {@link #Y_DIRECTION}.
+ * Determines which direction we use to calculate and set the velocity.
+ * @param factory The AnimationFactory is responsible for initializing and updating the
+ * SpringAnimations added to this class.
+ */
+ public SpringAnimationHandler(@Direction int direction, AnimationFactory<T> factory) {
+ mVelocityDirection = direction;
+ mAnimationFactory = factory;
}
- public SpringAnimation add(View view, int position, AlphabeticalAppsList apps, int appsPerRow,
- SpringAnimation recycle) {
- int numPredictedApps = Math.min(appsPerRow, apps.getPredictedApps().size());
- int appPosition = getAppPosition(position, numPredictedApps, appsPerRow);
-
- int col = appPosition % appsPerRow;
- int row = appPosition / appsPerRow;
-
- int numTotalRows = apps.getNumAppRows() - 1; // zero offset
- if (row > (numTotalRows / 2)) {
- // Mirror the rows so that the top row acts the same as the bottom row.
- row = Math.abs(numTotalRows - row);
+ /**
+ * Adds a new or recycled animation to the list of springs handled by this class.
+ *
+ * @param view The view the spring is attached to.
+ * @param object Used to initialize and update the spring.
+ */
+ public void add(View view, T object) {
+ SpringAnimation spring = (SpringAnimation) view.getTag(R.id.spring_animation_tag);
+ if (spring == null) {
+ spring = mAnimationFactory.initialize(object);
+ view.setTag(R.id.spring_animation_tag, spring);
}
-
- // We manipulate the stiffness, min, and max values based on the items distance to the first
- // row and the items distance to the center column to create the ^-shaped motion effect.
- float rowFactor = (1 + row) * 0.5f;
- float colFactor = getColumnFactor(col, appsPerRow);
-
- float minValue = DEFAULT_MIN_VALUE * (rowFactor + colFactor);
- float maxValue = DEFAULT_MAX_VALUE * (rowFactor + colFactor);
-
- float stiffness = Utilities.boundToRange(MAX_SPRING_STIFFNESS - (row * 50f),
- MIN_SPRING_STIFFNESS, MAX_SPRING_STIFFNESS);
-
- SpringAnimation animation = (recycle != null ? recycle : createSpringAnimation(view))
- .setStartVelocity(mCurrentVelocity)
- .setMinValue(minValue)
- .setMaxValue(maxValue);
- animation.getSpring().setStiffness(stiffness);
-
- mAnimations.add(animation);
- return animation;
+ mAnimationFactory.update(spring, object);
+ spring.setStartVelocity(mCurrentVelocity);
+ mAnimations.add(spring);
}
- public SpringAnimation remove(SpringAnimation animation) {
- animation.skipToEnd();
+ /**
+ * Stops and removes the spring attached to {@param view}.
+ */
+ public void remove(View view) {
+ SpringAnimation animation = (SpringAnimation) view.getTag(R.id.spring_animation_tag);
+ if (animation.canSkipToEnd()) {
+ animation.skipToEnd();
+ }
mAnimations.remove(animation);
- return animation;
}
public void addMovement(MotionEvent event) {
@@ -149,7 +138,9 @@ public class SpringAnimationHandler {
int size = mAnimations.size();
for (int i = 0; i < size; ++i) {
- mAnimations.get(i).skipToEnd();
+ if (mAnimations.get(i).canSkipToEnd()) {
+ mAnimations.get(i).skipToEnd();
+ }
}
}
@@ -169,84 +160,55 @@ public class SpringAnimationHandler {
}
private void computeVelocity() {
- getVelocityTracker().computeCurrentVelocity(175);
+ getVelocityTracker().computeCurrentVelocity(1000 /* millis */);
mCurrentVelocity = isVerticalDirection()
? getVelocityTracker().getYVelocity()
: getVelocityTracker().getXVelocity();
+ mCurrentVelocity *= VELOCITY_DAMPING_FACTOR;
mShouldComputeVelocity = false;
if (DEBUG) Log.d(TAG, "computeVelocity=" + mCurrentVelocity);
}
private boolean isVerticalDirection() {
- return mDirection == Y_DIRECTION;
+ return mVelocityDirection == Y_DIRECTION;
}
- private SpringAnimation createSpringAnimation(View view) {
- DynamicAnimation.ViewProperty property = isVerticalDirection()
- ? DynamicAnimation.TRANSLATION_Y
- : DynamicAnimation.TRANSLATION_X;
-
- return new SpringAnimation(view, property, 0)
- .setStartValue(1f)
- .setSpring(new SpringForce(0)
- .setDampingRatio(SPRING_DAMPING_RATIO));
+ private VelocityTracker getVelocityTracker() {
+ if (mVelocityTracker == null) {
+ mVelocityTracker = VelocityTracker.obtain();
+ }
+ return mVelocityTracker;
}
/**
- * @return The app position is the position of the app in the Adapter if we ignored all other
- * view types.
+ * This interface is used to initialize and update the SpringAnimations added to the
+ * {@link SpringAnimationHandler}.
*
- * ie. The first predicted app is at position 0, and the first app of all apps is
- * at {@param appsPerRow}.
+ * @param <T> The object that each SpringAnimation is attached to.
*/
- private int getAppPosition(int position, int numPredictedApps, int appsPerRow) {
- int appPosition = position;
- int numDividerViews = 1 + (numPredictedApps == 0 ? 0 : 1);
-
- int allAppsStartAt = numDividerViews + numPredictedApps;
- if (numDividerViews == 1 || position < allAppsStartAt) {
- appPosition -= 1;
- } else {
- // We cannot assume that the predicted row will always be full.
- int numPredictedAppsOffset = appsPerRow - numPredictedApps;
- appPosition = position + numPredictedAppsOffset - numDividerViews;
- }
+ public interface AnimationFactory<T> {
+
+ /**
+ * Initializes a new Spring for {@param object}.
+ */
+ SpringAnimation initialize(T object);
- return appPosition;
+ /**
+ * Updates the value of {@param spring} based on {@param object}.
+ */
+ void update(SpringAnimation spring, T object);
}
/**
- * Increase the column factor as the distance increases between the column and the center
- * column(s).
+ * Helper method to create a new SpringAnimation for {@param view}.
*/
- private float getColumnFactor(int col, int numCols) {
- float centerColumn = numCols / 2;
- int distanceToCenter = (int) Math.abs(col - centerColumn);
-
- boolean evenNumberOfColumns = numCols % 2 == 0;
- if (evenNumberOfColumns && col < centerColumn) {
- distanceToCenter -= 1;
- }
-
- float factor = 0;
- while (distanceToCenter > 0) {
- if (distanceToCenter == 1) {
- factor += 0.2f;
- } else {
- factor += 0.1f;
- }
- --distanceToCenter;
- }
-
- return factor;
+ public static SpringAnimation forView(View view, FloatPropertyCompat property, float finalPos) {
+ SpringAnimation spring = new SpringAnimation(view, property, finalPos);
+ spring.setStartValue(1f);
+ spring.setSpring(new SpringForce(finalPos));
+ return spring;
}
- private VelocityTracker getVelocityTracker() {
- if (mVelocityTracker == null) {
- mVelocityTracker = VelocityTracker.obtain();
- }
- return mVelocityTracker;
- }
}