From 0f3af75eb044ec7ec7f41c80c20ccab43d749567 Mon Sep 17 00:00:00 2001 From: Sunny Goyal Date: Fri, 8 Jun 2018 13:01:04 -0700 Subject: [PATCH] Making the self always follow the vertical progress without any min height limit. After a certain height, the self fades out, but keeps following the vertical progress. Eventually the fade-out can be decoupled from vertical progress and tied to the state Bug: 109829614 Change-Id: I9808ed3fa1730b938196bc6d3518a6d096a13f4c --- quickstep/res/values/dimens.xml | 2 + .../quickstep/views/ShelfScrimView.java | 128 ++++++++++-------- src/com/android/launcher3/Utilities.java | 6 +- .../android/launcher3/anim/Interpolators.java | 3 +- .../android/launcher3/views/ScrimView.java | 22 ++- 5 files changed, 91 insertions(+), 70 deletions(-) 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);