diff --git a/quickstep/res/values/dimens.xml b/quickstep/res/values/dimens.xml
index acfc180ada..ea7d21b540 100644
--- a/quickstep/res/values/dimens.xml
+++ b/quickstep/res/values/dimens.xml
@@ -54,4 +54,6 @@
168dp
16dp
+
+ 24dp
diff --git a/quickstep/src/com/android/quickstep/views/ShelfScrimView.java b/quickstep/src/com/android/quickstep/views/ShelfScrimView.java
index c780b62340..d7e527c7c6 100644
--- a/quickstep/src/com/android/quickstep/views/ShelfScrimView.java
+++ b/quickstep/src/com/android/quickstep/views/ShelfScrimView.java
@@ -15,11 +15,11 @@
*/
package com.android.quickstep.views;
-import static android.support.v4.graphics.ColorUtils.compositeColors;
import static android.support.v4.graphics.ColorUtils.setAlphaComponent;
import static com.android.launcher3.LauncherState.OVERVIEW;
-import static com.android.launcher3.anim.Interpolators.ACCEL_2;
+import static com.android.launcher3.anim.Interpolators.ACCEL;
+import static com.android.launcher3.anim.Interpolators.LINEAR;
import android.content.Context;
import android.graphics.Canvas;
@@ -32,7 +32,7 @@ import android.util.AttributeSet;
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.R;
-import com.android.launcher3.uioverrides.OverviewState;
+import com.android.launcher3.Utilities;
import com.android.launcher3.util.Themes;
import com.android.launcher3.views.ScrimView;
@@ -45,22 +45,30 @@ import com.android.launcher3.views.ScrimView;
*/
public class ShelfScrimView extends ScrimView {
+ // If the progress is more than this, shelf follows the finger, otherwise it moves faster to
+ // cover the whole screen
+ private static final float SCRIM_CATCHUP_THRESHOLD = 0.2f;
+
// In transposed layout, we simply draw a flat color.
private boolean mDrawingFlatColor;
// For shelf mode
private final int mEndAlpha;
- private final int mThresholdAlpha;
private final float mRadius;
private final float mMaxScrimAlpha;
private final Paint mPaint;
- // Max vertical progress after which the scrim stops moving.
- private float mMoveThreshold;
- // Minimum visible size of the scrim.
- private int mMinSize;
+ // Mid point where the alpha changes
+ private int mMidAlpha;
+ private float mMidProgress;
+
+ private float mShiftRange;
+
+ private final float mShelfOffset;
+ private float mTopOffset;
+ private float mShelfTop;
+ private float mShelfTopAtThreshold;
- private float mScrimMoveFactor = 0;
private int mShelfColor;
private int mRemainingScreenColor;
@@ -73,10 +81,10 @@ public class ShelfScrimView extends ScrimView {
mMaxScrimAlpha = OVERVIEW.getWorkspaceScrimAlpha(mLauncher);
mEndAlpha = Color.alpha(mEndScrim);
- mThresholdAlpha = Themes.getAttrInteger(context, R.attr.allAppsInterimScrimAlpha);
mRadius = mLauncher.getResources().getDimension(R.dimen.shelf_surface_radius);
mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
+ mShelfOffset = context.getResources().getDimension(R.dimen.shelf_surface_offset);
// Just assume the easiest UI for now, until we have the proper layout information.
mDrawingFlatColor = true;
}
@@ -93,10 +101,15 @@ public class ShelfScrimView extends ScrimView {
mDrawingFlatColor = dp.isVerticalBarLayout();
if (!mDrawingFlatColor) {
- float swipeLength = OverviewState.getDefaultSwipeHeight(mLauncher);
- mMoveThreshold = 1 - swipeLength / mLauncher.getAllAppsController().getShiftRange();
- mMinSize = dp.hotseatBarSizePx + dp.getInsets().bottom;
mRemainingScreenPathValid = false;
+ mShiftRange = mLauncher.getAllAppsController().getShiftRange();
+
+ mMidProgress = OVERVIEW.getVerticalProgress(mLauncher);
+ mMidAlpha = mMidProgress >= 1 ? 0
+ : Themes.getAttrInteger(getContext(), R.attr.allAppsInterimScrimAlpha);
+
+ mTopOffset = dp.getInsets().top - mShelfOffset;
+ mShelfTopAtThreshold = mShiftRange * SCRIM_CATCHUP_THRESHOLD + mTopOffset;
updateColors();
}
updateDragHandleAlpha();
@@ -107,82 +120,79 @@ public class ShelfScrimView extends ScrimView {
public void updateColors() {
super.updateColors();
if (mDrawingFlatColor) {
+ mDragHandleOffset = 0;
return;
}
- if (mProgress >= mMoveThreshold) {
- mScrimMoveFactor = 1;
-
- if (mProgress >= 1) {
- mShelfColor = 0;
- } else {
- int alpha = Math.round(mThresholdAlpha * ACCEL_2.getInterpolation(
- (1 - mProgress) / (1 - mMoveThreshold)));
- mShelfColor = setAlphaComponent(mEndScrim, alpha);
- }
-
- mRemainingScreenColor = 0;
- } else if (mProgress <= 0) {
- mScrimMoveFactor = 0;
- mShelfColor = mCurrentFlatColor;
- mRemainingScreenColor = 0;
-
+ mDragHandleOffset = mShelfOffset - mDragHandleSize;
+ if (mProgress >= SCRIM_CATCHUP_THRESHOLD) {
+ mShelfTop = mShiftRange * mProgress + mTopOffset;
} else {
- mScrimMoveFactor = mProgress / mMoveThreshold;
- mRemainingScreenColor = setAlphaComponent(mScrimColor,
- Math.round((1 - mScrimMoveFactor) * mMaxScrimAlpha * 255));
+ mShelfTop = Utilities.mapRange(mProgress / SCRIM_CATCHUP_THRESHOLD, -mRadius,
+ mShelfTopAtThreshold);
+ }
- // Merge the remainingScreenColor and shelfColor in one to avoid overdraw.
- int alpha = mEndAlpha - Math.round((mEndAlpha - mThresholdAlpha) * mScrimMoveFactor);
- mShelfColor = compositeColors(setAlphaComponent(mEndScrim, alpha),
- mRemainingScreenColor);
+ if (mProgress >= 1) {
+ mRemainingScreenColor = 0;
+ mShelfColor = 0;
+ } else if (mProgress >= mMidProgress) {
+ mRemainingScreenColor = 0;
+
+ int alpha = Math.round(Utilities.mapToRange(
+ mProgress, mMidProgress, 1, mMidAlpha, 0, ACCEL));
+ mShelfColor = setAlphaComponent(mEndScrim, alpha);
+ } else {
+ mDragHandleOffset += mShiftRange * (mMidProgress - mProgress);
+
+ int alpha = Math.round(
+ Utilities.mapToRange(mProgress, (float) 0, mMidProgress, (float) mEndAlpha,
+ (float) mMidAlpha, LINEAR));
+ mShelfColor = setAlphaComponent(mEndScrim, alpha);
+
+ int remainingScrimAlpha = Math.round(
+ Utilities.mapToRange(mProgress, (float) 0, mMidProgress, mMaxScrimAlpha,
+ (float) 0, LINEAR));
+ mRemainingScreenColor = setAlphaComponent(mScrimColor, remainingScrimAlpha);
}
}
@Override
protected void onDraw(Canvas canvas) {
- float translate = drawBackground(canvas);
-
- if (mDragHandle != null) {
- canvas.translate(0, -translate);
- mDragHandle.draw(canvas);
- canvas.translate(0, translate);
- }
+ drawBackground(canvas);
+ drawDragHandle(canvas);
}
- private float drawBackground(Canvas canvas) {
+ private void drawBackground(Canvas canvas) {
if (mDrawingFlatColor) {
if (mCurrentFlatColor != 0) {
canvas.drawColor(mCurrentFlatColor);
}
- return 0;
+ return;
}
- if (mShelfColor == 0) {
- return 0;
- } else if (mScrimMoveFactor <= 0) {
+ if (Color.alpha(mShelfColor) == 0) {
+ return;
+ } else if (mProgress <= 0) {
canvas.drawColor(mShelfColor);
- return getHeight();
+ return;
}
- float minTop = getHeight() - mMinSize;
- float top = minTop * mScrimMoveFactor - mDragHandleSize;
-
+ int height = getHeight();
+ int width = getWidth();
// Draw the scrim over the remaining screen if needed.
if (mRemainingScreenColor != 0) {
if (!mRemainingScreenPathValid) {
mTempPath.reset();
// Using a arbitrary '+10' in the bottom to avoid any left-overs at the
// corners due to rounding issues.
- mTempPath.addRoundRect(0, minTop, getWidth(), getHeight() + mRadius + 10,
+ mTempPath.addRoundRect(0, height - mRadius, width, height + mRadius + 10,
mRadius, mRadius, Direction.CW);
-
mRemainingScreenPath.reset();
- mRemainingScreenPath.addRect(0, 0, getWidth(), getHeight(), Direction.CW);
+ mRemainingScreenPath.addRect(0, 0, width, height, Direction.CW);
mRemainingScreenPath.op(mTempPath, Op.DIFFERENCE);
}
- float offset = minTop - top;
+ float offset = height - mRadius - mShelfTop;
canvas.translate(0, -offset);
mPaint.setColor(mRemainingScreenColor);
canvas.drawPath(mRemainingScreenPath, mPaint);
@@ -190,8 +200,6 @@ public class ShelfScrimView extends ScrimView {
}
mPaint.setColor(mShelfColor);
- canvas.drawRoundRect(0, top, getWidth(), getHeight() + mRadius,
- mRadius, mRadius, mPaint);
- return minTop - mDragHandleSize - top;
+ canvas.drawRoundRect(0, mShelfTop, width, height + mRadius, mRadius, mRadius, mPaint);
}
}
diff --git a/src/com/android/launcher3/Utilities.java b/src/com/android/launcher3/Utilities.java
index 5355c5e551..7fe8d35cb6 100644
--- a/src/com/android/launcher3/Utilities.java
+++ b/src/com/android/launcher3/Utilities.java
@@ -48,6 +48,7 @@ import android.util.Log;
import android.util.Pair;
import android.util.TypedValue;
import android.view.View;
+import android.view.animation.Interpolator;
import com.android.launcher3.config.FeatureFlags;
@@ -281,13 +282,14 @@ public final class Utilities {
* @param toMax The upper bound of the range that t is being mapped to.
* @return The mapped value of t.
*/
- public static float mapToRange(float t, float fromMin, float fromMax, float toMin, float toMax) {
+ public static float mapToRange(float t, float fromMin, float fromMax, float toMin, float toMax,
+ Interpolator interpolator) {
if (fromMin == fromMax || toMin == toMax) {
Log.e(TAG, "mapToRange: range has 0 length");
return toMin;
}
float progress = Math.abs(t - fromMin) / Math.abs(fromMax - fromMin);
- return mapRange(progress, toMin, toMax);
+ return mapRange(interpolator.getInterpolation(progress), toMin, toMax);
}
public static float mapRange(float value, float min, float max) {
diff --git a/src/com/android/launcher3/anim/Interpolators.java b/src/com/android/launcher3/anim/Interpolators.java
index d17572e6cc..a4cba4f62e 100644
--- a/src/com/android/launcher3/anim/Interpolators.java
+++ b/src/com/android/launcher3/anim/Interpolators.java
@@ -158,7 +158,6 @@ public class Interpolators {
*/
public static Interpolator mapToProgress(Interpolator interpolator, float lowerBound,
float upperBound) {
- return t -> Utilities.mapToRange(interpolator.getInterpolation(t), 0, 1,
- lowerBound, upperBound);
+ return t -> Utilities.mapRange(interpolator.getInterpolation(t), lowerBound, upperBound);
}
}
\ No newline at end of file
diff --git a/src/com/android/launcher3/views/ScrimView.java b/src/com/android/launcher3/views/ScrimView.java
index 6e3ef07052..7066980a9d 100644
--- a/src/com/android/launcher3/views/ScrimView.java
+++ b/src/com/android/launcher3/views/ScrimView.java
@@ -109,6 +109,7 @@ public class ScrimView extends View implements Insettable, OnChangeListener,
protected int mEndFlatColorAlpha;
protected final int mDragHandleSize;
+ protected float mDragHandleOffset;
private final Rect mDragHandleBounds;
private final RectF mHitRect = new RectF();
@@ -223,8 +224,14 @@ public class ScrimView extends View implements Insettable, OnChangeListener,
if (mCurrentFlatColor != 0) {
canvas.drawColor(mCurrentFlatColor);
}
+ drawDragHandle(canvas);
+ }
+
+ protected void drawDragHandle(Canvas canvas) {
if (mDragHandle != null) {
+ canvas.translate(0, -mDragHandleOffset);
mDragHandle.draw(canvas);
+ canvas.translate(0, mDragHandleOffset);
}
}
@@ -237,20 +244,23 @@ public class ScrimView extends View implements Insettable, OnChangeListener,
final Drawable drawable = mDragHandle;
mDragHandle = null;
- drawable.setBounds(mDragHandleBounds);
- Rect topBounds = new Rect(mDragHandleBounds);
- topBounds.offset(0, -mDragHandleBounds.height() / 2);
+ Rect bounds = new Rect(mDragHandleBounds);
+ bounds.offset(0, -(int) mDragHandleOffset);
+ drawable.setBounds(bounds);
- Rect invalidateRegion = new Rect(mDragHandleBounds);
+ Rect topBounds = new Rect(bounds);
+ topBounds.offset(0, -bounds.height() / 2);
+
+ Rect invalidateRegion = new Rect(bounds);
invalidateRegion.top = topBounds.top;
Keyframe frameTop = Keyframe.ofObject(0.6f, topBounds);
frameTop.setInterpolator(DEACCEL);
- Keyframe frameBot = Keyframe.ofObject(1, mDragHandleBounds);
+ Keyframe frameBot = Keyframe.ofObject(1, bounds);
frameBot.setInterpolator(ACCEL);
PropertyValuesHolder holder = PropertyValuesHolder .ofKeyframe("bounds",
- Keyframe.ofObject(0, mDragHandleBounds), frameTop, frameBot);
+ Keyframe.ofObject(0, bounds), frameTop, frameBot);
holder.setEvaluator(new RectEvaluator());
ObjectAnimator anim = ObjectAnimator.ofPropertyValuesHolder(drawable, holder);