summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPeter Schiller <peterschiller@google.com>2016-07-29 17:05:30 -0700
committerPeter Schiller <peterschiller@google.com>2016-08-02 17:54:18 -0700
commite6fe1b59470b653f0275596cb8a211367dd61654 (patch)
tree66150275c18df1df97bddf8613d222ee07030cda
parenta659bfe3d2fd28a06fb04c3ca08238ec3f94f6e2 (diff)
downloadandroid_packages_apps_Trebuchet-e6fe1b59470b653f0275596cb8a211367dd61654.tar.gz
android_packages_apps_Trebuchet-e6fe1b59470b653f0275596cb8a211367dd61654.tar.bz2
android_packages_apps_Trebuchet-e6fe1b59470b653f0275596cb8a211367dd61654.zip
Simpler caret
Bug: 30527159 Change-Id: I674de149e613c7adb567a13a288baa9877d36112
-rw-r--r--res/interpolator/caret_animation_interpolator.xml4
-rw-r--r--src/com/android/launcher3/allapps/AllAppsCaretController.java122
-rw-r--r--src/com/android/launcher3/allapps/AllAppsTransitionController.java70
3 files changed, 129 insertions, 67 deletions
diff --git a/res/interpolator/caret_animation_interpolator.xml b/res/interpolator/caret_animation_interpolator.xml
deleted file mode 100644
index 25af4bc0f..000000000
--- a/res/interpolator/caret_animation_interpolator.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<pathInterpolator
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:pathData="M 0.0,0.0 c 0.0001,0.0 0.0,1.0 1.0,1.0" />
diff --git a/src/com/android/launcher3/allapps/AllAppsCaretController.java b/src/com/android/launcher3/allapps/AllAppsCaretController.java
new file mode 100644
index 000000000..622322bfc
--- /dev/null
+++ b/src/com/android/launcher3/allapps/AllAppsCaretController.java
@@ -0,0 +1,122 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.launcher3.allapps;
+
+import android.animation.ObjectAnimator;
+import android.view.animation.AnimationUtils;
+import android.view.animation.Interpolator;
+
+import com.android.launcher3.Launcher;
+import com.android.launcher3.R;
+import com.android.launcher3.pageindicators.CaretDrawable;
+
+public class AllAppsCaretController {
+ // Determines when the caret should flip. Should be accessed via getThreshold()
+ private static final float CARET_THRESHOLD = 0.015f;
+ private static final float CARET_THRESHOLD_LAND = 0.5f;
+ // The velocity at which the caret will peak (i.e. exhibit a 90 degree bend)
+ private static final float PEAK_VELOCITY = VerticalPullDetector.RELEASE_VELOCITY_PX_MS * .7f;
+
+ private Launcher mLauncher;
+
+ private ObjectAnimator mCaretAnimator;
+ private CaretDrawable mCaretDrawable;
+ private float mLastCaretProgress;
+ private boolean mThresholdCrossed;
+
+ public AllAppsCaretController(CaretDrawable caret, Launcher launcher) {
+ mLauncher = launcher;
+ mCaretDrawable = caret;
+
+ final long caretAnimationDuration = launcher.getResources().getInteger(
+ R.integer.config_caretAnimationDuration);
+ final Interpolator caretInterpolator = AnimationUtils.loadInterpolator(launcher,
+ android.R.interpolator.fast_out_slow_in);
+
+ // We will set values later
+ mCaretAnimator = ObjectAnimator.ofFloat(mCaretDrawable, "caretProgress", 0);
+ mCaretAnimator.setDuration(caretAnimationDuration);
+ mCaretAnimator.setInterpolator(caretInterpolator);
+ }
+
+ /**
+ * Updates the state of the caret based on the progress of the {@link AllAppsContainerView}, as
+ * defined by the {@link AllAppsTransitionController}. Uses the container's velocity to adjust
+ * angle of caret.
+ *
+ * @param containerProgress The progress of the container in the range [0..1]
+ * @param velocity The velocity of the container
+ * @param dragging {@code true} if the container is being dragged
+ */
+ public void updateCaret(float containerProgress, float velocity, boolean dragging) {
+ // If we're in portrait and the shift is not 0 or 1, adjust the caret based on velocity
+ if (getThreshold() < containerProgress && containerProgress < 1 - getThreshold() &&
+ !mLauncher.useVerticalBarLayout()) {
+ mThresholdCrossed = true;
+
+ // How fast are we moving as a percentage of the peak velocity?
+ final float pctOfFlingVelocity = Math.max(-1, Math.min(velocity / PEAK_VELOCITY, 1));
+
+ mCaretDrawable.setCaretProgress(pctOfFlingVelocity);
+
+ // Set the last caret progress to this progress to prevent animator cancellation
+ mLastCaretProgress = pctOfFlingVelocity;
+ // Animate to neutral. This is necessary so the caret doesn't "freeze" when the
+ // container stops moving (e.g., during a drag or when the threshold is reached).
+ animateCaretToProgress(CaretDrawable.PROGRESS_CARET_NEUTRAL);
+ } else if (!dragging) {
+ // Otherwise, if we're not dragging, match the caret to the appropriate state
+ if (containerProgress <= getThreshold()) { // All Apps is up
+ animateCaretToProgress(CaretDrawable.PROGRESS_CARET_POINTING_DOWN);
+ } else if (containerProgress >= 1 - getThreshold()) { // All Apps is down
+ animateCaretToProgress(CaretDrawable.PROGRESS_CARET_POINTING_UP);
+ }
+ }
+ }
+
+ private void animateCaretToProgress(float progress) {
+ // If the new progress is the same as the last progress we animated to, terminate early
+ if (Float.compare(mLastCaretProgress, progress) == 0) {
+ return;
+ }
+
+ if (mCaretAnimator.isRunning()) {
+ mCaretAnimator.cancel(); // Stop the animator in its tracks
+ }
+
+ // Update the progress and start the animation
+ mLastCaretProgress = progress;
+ mCaretAnimator.setFloatValues(progress);
+ mCaretAnimator.start();
+ }
+
+ private float getThreshold() {
+ // In landscape, just return the landscape threshold.
+ if (mLauncher.useVerticalBarLayout()) {
+ return CARET_THRESHOLD_LAND;
+ }
+
+ // Before the threshold is crossed, it is reported as zero. This makes the caret immediately
+ // responsive when a drag begins. After the threshold is crossed, we return the constant
+ // value. This means the caret will start its state-based adjustment sooner. That is, we
+ // won't have to wait until the panel is completely settled to begin animation.
+ return mThresholdCrossed ? CARET_THRESHOLD : 0f;
+ }
+
+ public void onDragStart() {
+ mThresholdCrossed = false;
+ }
+}
diff --git a/src/com/android/launcher3/allapps/AllAppsTransitionController.java b/src/com/android/launcher3/allapps/AllAppsTransitionController.java
index eb6c92628..a8c0422c9 100644
--- a/src/com/android/launcher3/allapps/AllAppsTransitionController.java
+++ b/src/com/android/launcher3/allapps/AllAppsTransitionController.java
@@ -11,7 +11,6 @@ import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.animation.AccelerateInterpolator;
-import android.view.animation.AnimationUtils;
import android.view.animation.Interpolator;
import com.android.launcher3.DeviceProfile;
@@ -22,7 +21,6 @@ import com.android.launcher3.PagedView;
import com.android.launcher3.R;
import com.android.launcher3.Utilities;
import com.android.launcher3.Workspace;
-import com.android.launcher3.pageindicators.CaretDrawable;
import com.android.launcher3.userevent.nano.LauncherLogProto;
import com.android.launcher3.util.TouchController;
@@ -56,11 +54,7 @@ public class AllAppsTransitionController implements TouchController, VerticalPul
private Hotseat mHotseat;
private int mHotseatBackgroundColor;
- private ObjectAnimator mCaretAnimator;
- private final long mCaretAnimationDuration;
- private final Interpolator mCaretInterpolator;
- private CaretDrawable mCaretDrawable;
- private float mLastCaretProgress;
+ private AllAppsCaretController mCaretController;
private float mStatusBarHeight;
@@ -105,11 +99,6 @@ public class AllAppsTransitionController implements TouchController, VerticalPul
mBezelSwipeUpHeight = l.getResources().getDimensionPixelSize(
R.dimen.all_apps_bezel_swipe_height);
- mCaretAnimationDuration = l.getResources().getInteger(
- R.integer.config_caretAnimationDuration);
- mCaretInterpolator = AnimationUtils.loadInterpolator(l,
- R.interpolator.caret_animation_interpolator);
-
mEvaluator = new ArgbEvaluator();
mAllAppsBackgroundColor = l.getColor(R.color.all_apps_container_color);
}
@@ -196,6 +185,7 @@ public class AllAppsTransitionController implements TouchController, VerticalPul
@Override
public void onDragStart(boolean start) {
+ mCaretController.onDragStart();
cancelAnimation();
mCurrentAnimation = LauncherAnimUtils.createAnimatorSet();
mShiftStart = mAppsView.getTranslationY();
@@ -336,19 +326,15 @@ public class AllAppsTransitionController implements TouchController, VerticalPul
return;
}
mWorkspace.setWorkspaceYTranslationAndAlpha(
- PARALLAX_COEFFICIENT * (-mShiftRange + shiftCurrent),
- interpolation);
- updateCaret(progress);
- updateLightStatusBar(shiftCurrent);
+ PARALLAX_COEFFICIENT * (-mShiftRange + shiftCurrent), interpolation);
if (!mDetector.isDraggingState()) {
mContainerVelocity = mDetector.computeVelocity(shiftCurrent - shiftPrevious,
System.currentTimeMillis());
}
- }
- public float getContainerVelocity() {
- return mContainerVelocity;
+ mCaretController.updateCaret(progress, mContainerVelocity, mDetector.isDraggingState());
+ updateLightStatusBar(shiftCurrent);
}
public float getProgress() {
@@ -513,56 +499,14 @@ public class AllAppsTransitionController implements TouchController, VerticalPul
mCurrentAnimation = null;
}
- private void updateCaret(float shift) {
- // Animate to a neutral state by default
- float newCaretProgress = CaretDrawable.PROGRESS_CARET_NEUTRAL;
-
- // If we're in portrait and the shift is not 0 or 1, adjust the caret based on velocity
- if (0f < shift && shift < 1f && !mLauncher.useVerticalBarLayout()) {
- // How fast are we moving as a percentage of the minimum fling velocity?
- final float pctOfFlingVelocity = Math.max(-1, Math.min(
- mContainerVelocity / VerticalPullDetector.RELEASE_VELOCITY_PX_MS, 1));
-
- mCaretDrawable.setCaretProgress(pctOfFlingVelocity);
-
- // Set the last caret progress to this progress to prevent animator cancellation
- mLastCaretProgress = pctOfFlingVelocity;
- } else if (!mDetector.isDraggingState()) {
- // Otherwise, if we're not dragging, match the caret to the appropriate state
- if (Float.compare(shift, 0f) == 0) { // All Apps is up
- newCaretProgress = CaretDrawable.PROGRESS_CARET_POINTING_DOWN;
- } else if (Float.compare(shift, 1f) == 0) { // All Apps is down
- newCaretProgress = CaretDrawable.PROGRESS_CARET_POINTING_UP;
- }
- }
-
- // If the new progress is the same as the last progress we animated to, terminate early
- if (Float.compare(mLastCaretProgress, newCaretProgress) == 0) {
- return;
- }
-
- if (mCaretAnimator.isRunning()) {
- mCaretAnimator.cancel(); // Stop the animator in its tracks
- }
-
- // Update the progress and start the animation
- mLastCaretProgress = newCaretProgress;
- mCaretAnimator.setFloatValues(newCaretProgress);
- mCaretAnimator.start();
- }
-
public void setupViews(AllAppsContainerView appsView, Hotseat hotseat, Workspace workspace) {
mAppsView = appsView;
mHotseat = hotseat;
mWorkspace = workspace;
- mCaretDrawable = mWorkspace.getPageIndicator().getCaretDrawable();
mHotseat.addOnLayoutChangeListener(this);
mHotseat.bringToFront();
-
- // we will set values later
- mCaretAnimator = ObjectAnimator.ofFloat(mCaretDrawable, "caretProgress", 0);
- mCaretAnimator.setDuration(mCaretAnimationDuration);
- mCaretAnimator.setInterpolator(mCaretInterpolator);
+ mCaretController = new AllAppsCaretController(
+ mWorkspace.getPageIndicator().getCaretDrawable(), mLauncher);
}
@Override