summaryrefslogtreecommitdiffstats
path: root/src/com/android/launcher3/allapps
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/allapps
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/allapps')
-rw-r--r--src/com/android/launcher3/allapps/AllAppsContainerView.java5
-rw-r--r--src/com/android/launcher3/allapps/AllAppsGridAdapter.java146
2 files changed, 134 insertions, 17 deletions
diff --git a/src/com/android/launcher3/allapps/AllAppsContainerView.java b/src/com/android/launcher3/allapps/AllAppsContainerView.java
index f1616fc09..c3df07360 100644
--- a/src/com/android/launcher3/allapps/AllAppsContainerView.java
+++ b/src/com/android/launcher3/allapps/AllAppsContainerView.java
@@ -91,9 +91,8 @@ public class AllAppsContainerView extends BaseContainerView implements DragSourc
mLauncher = Launcher.getLauncher(context);
mApps = new AlphabeticalAppsList(context);
- mSpringAnimationHandler = new SpringAnimationHandler(SpringAnimationHandler.Y_DIRECTION);
- mAdapter = new AllAppsGridAdapter(mLauncher, mApps, mLauncher, this,
- mSpringAnimationHandler);
+ mAdapter = new AllAppsGridAdapter(mLauncher, mApps, mLauncher, this);
+ mSpringAnimationHandler = mAdapter.getSpringAnimationHandler();
mApps.setAdapter(mAdapter);
mLayoutManager = mAdapter.getLayoutManager();
mSearchQueryBuilder = new SpannableStringBuilder();
diff --git a/src/com/android/launcher3/allapps/AllAppsGridAdapter.java b/src/com/android/launcher3/allapps/AllAppsGridAdapter.java
index d3d23ca24..9c7372f2c 100644
--- a/src/com/android/launcher3/allapps/AllAppsGridAdapter.java
+++ b/src/com/android/launcher3/allapps/AllAppsGridAdapter.java
@@ -19,6 +19,7 @@ import android.content.Context;
import android.content.Intent;
import android.content.res.Resources;
import android.graphics.Point;
+import android.support.animation.DynamicAnimation;
import android.support.animation.SpringAnimation;
import android.support.v4.view.accessibility.AccessibilityEventCompat;
import android.support.v4.view.accessibility.AccessibilityNodeInfoCompat;
@@ -38,6 +39,7 @@ import com.android.launcher3.AppInfo;
import com.android.launcher3.BubbleTextView;
import com.android.launcher3.Launcher;
import com.android.launcher3.R;
+import com.android.launcher3.Utilities;
import com.android.launcher3.allapps.AlphabeticalAppsList.AdapterItem;
import com.android.launcher3.anim.SpringAnimationHandler;
import com.android.launcher3.config.FeatureFlags;
@@ -96,11 +98,6 @@ public class AllAppsGridAdapter extends RecyclerView.Adapter<AllAppsGridAdapter.
*/
public static class ViewHolder extends RecyclerView.ViewHolder {
- /**
- * Springs used for items where isViewType(viewType, VIEW_TYPE_MASK_HAS_SPRINGS) is true.
- */
- private SpringAnimation spring;
-
public ViewHolder(View v) {
super(v);
}
@@ -213,11 +210,10 @@ public class AllAppsGridAdapter extends RecyclerView.Adapter<AllAppsGridAdapter.
// The intent to send off to the market app, updated each time the search query changes.
private Intent mMarketSearchIntent;
- private SpringAnimationHandler mSpringAnimationHandler;
+ private SpringAnimationHandler<ViewHolder> mSpringAnimationHandler;
public AllAppsGridAdapter(Launcher launcher, AlphabeticalAppsList apps, View.OnClickListener
- iconClickListener, View.OnLongClickListener iconLongClickListener,
- SpringAnimationHandler springAnimationHandler) {
+ iconClickListener, View.OnLongClickListener iconLongClickListener) {
Resources res = launcher.getResources();
mLauncher = launcher;
mApps = apps;
@@ -228,7 +224,14 @@ public class AllAppsGridAdapter extends RecyclerView.Adapter<AllAppsGridAdapter.
mLayoutInflater = LayoutInflater.from(launcher);
mIconClickListener = iconClickListener;
mIconLongClickListener = iconLongClickListener;
- mSpringAnimationHandler = springAnimationHandler;
+ if (FeatureFlags.LAUNCHER3_PHYSICS) {
+ mSpringAnimationHandler = new SpringAnimationHandler<>(
+ SpringAnimationHandler.Y_DIRECTION, new AllAppsSpringAnimationFactory());
+ }
+ }
+
+ public SpringAnimationHandler getSpringAnimationHandler() {
+ return mSpringAnimationHandler;
}
public static boolean isDividerViewType(int viewType) {
@@ -292,8 +295,7 @@ public class AllAppsGridAdapter extends RecyclerView.Adapter<AllAppsGridAdapter.
R.layout.all_apps_icon, parent, false);
icon.setOnClickListener(mIconClickListener);
icon.setOnLongClickListener(mIconLongClickListener);
- icon.setLongPressTimeout(ViewConfiguration.get(parent.getContext())
- .getLongPressTimeout());
+ icon.setLongPressTimeout(ViewConfiguration.getLongPressTimeout());
icon.setOnFocusChangeListener(mIconFocusListener);
// Ensure the all apps icon height matches the workspace icons
@@ -386,8 +388,7 @@ public class AllAppsGridAdapter extends RecyclerView.Adapter<AllAppsGridAdapter.
public void onViewAttachedToWindow(ViewHolder holder) {
int type = holder.getItemViewType();
if (FeatureFlags.LAUNCHER3_PHYSICS && isViewType(type, VIEW_TYPE_MASK_HAS_SPRINGS)) {
- holder.spring = mSpringAnimationHandler.add(holder.itemView,
- holder.getAdapterPosition(), mApps, mAppsPerRow, holder.spring);
+ mSpringAnimationHandler.add(holder.itemView, holder);
}
}
@@ -395,7 +396,7 @@ public class AllAppsGridAdapter extends RecyclerView.Adapter<AllAppsGridAdapter.
public void onViewDetachedFromWindow(ViewHolder holder) {
int type = holder.getItemViewType();
if (FeatureFlags.LAUNCHER3_PHYSICS && isViewType(type, VIEW_TYPE_MASK_HAS_SPRINGS)) {
- holder.spring = mSpringAnimationHandler.remove(holder.spring);
+ mSpringAnimationHandler.remove(holder.itemView);
}
}
@@ -415,4 +416,121 @@ public class AllAppsGridAdapter extends RecyclerView.Adapter<AllAppsGridAdapter.
AlphabeticalAppsList.AdapterItem item = mApps.getAdapterItems().get(position);
return item.viewType;
}
+
+ /**
+ * Helper class to set the SpringAnimation values for an item in the adapter.
+ */
+ private class AllAppsSpringAnimationFactory
+ implements SpringAnimationHandler.AnimationFactory<ViewHolder> {
+ private static final float DEFAULT_MAX_VALUE_PX = 100;
+ private static final float DEFAULT_MIN_VALUE_PX = -DEFAULT_MAX_VALUE_PX;
+
+ // Damping ratio range is [0, 1]
+ private static final float SPRING_DAMPING_RATIO = 0.55f;
+
+ // Stiffness is a non-negative number.
+ private static final float MIN_SPRING_STIFFNESS = 580f;
+ private static final float MAX_SPRING_STIFFNESS = 900f;
+
+ // The amount by which each adjacent rows' stiffness will differ.
+ private static final float ROW_STIFFNESS_COEFFICIENT = 50f;
+
+ @Override
+ public SpringAnimation initialize(ViewHolder vh) {
+ return SpringAnimationHandler.forView(vh.itemView, DynamicAnimation.TRANSLATION_Y, 0);
+ }
+
+ /**
+ * @param spring A new or recycled SpringAnimation.
+ * @param vh The ViewHolder that {@param spring} is related to.
+ */
+ @Override
+ public void update(SpringAnimation spring, ViewHolder vh) {
+ int numPredictedApps = Math.min(mAppsPerRow, mApps.getPredictedApps().size());
+ int appPosition = getAppPosition(vh.getAdapterPosition(), numPredictedApps,
+ mAppsPerRow);
+
+ int col = appPosition % mAppsPerRow;
+ int row = appPosition / mAppsPerRow;
+
+ int numTotalRows = mApps.getNumAppRows() - 1; // zero-based count
+ if (row > (numTotalRows / 2)) {
+ // Mirror the rows so that the top row acts the same as the bottom row.
+ row = Math.abs(numTotalRows - row);
+ }
+
+ // 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, mAppsPerRow);
+
+ float minValue = DEFAULT_MIN_VALUE_PX * (rowFactor + colFactor);
+ float maxValue = DEFAULT_MAX_VALUE_PX * (rowFactor + colFactor);
+
+ float stiffness = Utilities.boundToRange(
+ MAX_SPRING_STIFFNESS - (row * ROW_STIFFNESS_COEFFICIENT),
+ MIN_SPRING_STIFFNESS,
+ MAX_SPRING_STIFFNESS);
+
+ spring.setMinValue(minValue)
+ .setMaxValue(maxValue)
+ .getSpring()
+ .setStiffness(stiffness)
+ .setDampingRatio(SPRING_DAMPING_RATIO);
+ }
+
+ /**
+ * @return The app position is the position of the app in the Adapter if we ignored all
+ * other view types.
+ *
+ * The first app is at position 0, and the first app each following row is at a
+ * position that is a multiple of {@param appsPerRow}.
+ *
+ * ie. If there are 5 apps per row, and there are two rows of apps:
+ * 0 1 2 3 4
+ * 5 6 7 8 9
+ */
+ 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;
+ }
+
+ return appPosition;
+ }
+
+ /**
+ * Increase the column factor as the distance increases between the column and the center
+ * column(s).
+ */
+ 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;
+ }
+ }
}