From a30b51ceb29e179caf7f441763ffeb6bfd336998 Mon Sep 17 00:00:00 2001 From: Peter Schiller Date: Wed, 13 Jul 2016 14:04:13 -0700 Subject: [PATCH] Adding stateful caret drawable Change-Id: Iba30da09f882297f789c405f932fef10617bba89 --- res/drawable/ic_allapps_caret.xml | 26 ------ res/interpolator/caret_animation_interpolator.xml | 4 + res/values/colors.xml | 1 + res/values/config.xml | 3 + res/values/dimens.xml | 6 +- .../LauncherStateTransitionAnimation.java | 2 +- src/com/android/launcher3/Workspace.java | 1 - .../allapps/AllAppsTransitionController.java | 42 +++++++++- .../launcher3/pageindicators/CaretDrawable.java | 98 ++++++++++++++++++++++ .../launcher3/pageindicators/PageIndicator.java | 26 +++++- .../PageIndicatorCaretLandscape.java | 12 +-- .../pageindicators/PageIndicatorLineCaret.java | 9 +- 12 files changed, 180 insertions(+), 50 deletions(-) delete mode 100644 res/drawable/ic_allapps_caret.xml create mode 100644 res/interpolator/caret_animation_interpolator.xml create mode 100644 src/com/android/launcher3/pageindicators/CaretDrawable.java diff --git a/res/drawable/ic_allapps_caret.xml b/res/drawable/ic_allapps_caret.xml deleted file mode 100644 index 34d1882dc..000000000 --- a/res/drawable/ic_allapps_caret.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - - - diff --git a/res/interpolator/caret_animation_interpolator.xml b/res/interpolator/caret_animation_interpolator.xml new file mode 100644 index 000000000..25af4bc0f --- /dev/null +++ b/res/interpolator/caret_animation_interpolator.xml @@ -0,0 +1,4 @@ + + diff --git a/res/values/colors.xml b/res/values/colors.xml index 937b2f05a..dccc53ef9 100644 --- a/res/values/colors.xml +++ b/res/values/colors.xml @@ -36,6 +36,7 @@ #FFFFFFFF #1E000000 + #FFFFFFFF #40FFFFFF #FFF diff --git a/res/values/config.xml b/res/values/config.xml index 47bfa30e1..a678958bb 100644 --- a/res/values/config.xml +++ b/res/values/config.xml @@ -57,6 +57,9 @@ 800 + + 200 + true diff --git a/res/values/dimens.xml b/res/values/dimens.xml index 1775d098f..38775f14f 100644 --- a/res/values/dimens.xml +++ b/res/values/dimens.xml @@ -58,7 +58,7 @@ 8dp 0dp - + 0dp 0dp 8dp @@ -74,8 +74,10 @@ 144dp 700dp 475dp + 2dp + 8dp - + 3dp 16dp 6dp diff --git a/src/com/android/launcher3/LauncherStateTransitionAnimation.java b/src/com/android/launcher3/LauncherStateTransitionAnimation.java index 6843d6096..41b81a9ba 100644 --- a/src/com/android/launcher3/LauncherStateTransitionAnimation.java +++ b/src/com/android/launcher3/LauncherStateTransitionAnimation.java @@ -677,7 +677,7 @@ public class LauncherStateTransitionAnimation { if (!animated || !initialized) { if (FeatureFlags.LAUNCHER3_ALL_APPS_PULL_UP && fromWorkspaceState == Workspace.State.NORMAL_HIDDEN) { - mAllAppsController.finishPullDown(); + mAllAppsController.finishPullDown(false); } fromView.setVisibility(View.GONE); dispatchOnLauncherTransitionPrepare(fromView, animated, multiplePagesVisible); diff --git a/src/com/android/launcher3/Workspace.java b/src/com/android/launcher3/Workspace.java index 7812a5bc1..344c389ef 100644 --- a/src/com/android/launcher3/Workspace.java +++ b/src/com/android/launcher3/Workspace.java @@ -1532,7 +1532,6 @@ public class Workspace extends PagedView float finalAlpha = mHotseatAlpha[0] * mHotseatAlpha[1] * mHotseatAlpha[2]; mLauncher.getHotseat().setAlpha(finalAlpha); - mPageIndicator.setAlpha(finalAlpha); } public ValueAnimator createHotseatAlphaAnimator(float finalValue) { diff --git a/src/com/android/launcher3/allapps/AllAppsTransitionController.java b/src/com/android/launcher3/allapps/AllAppsTransitionController.java index 41e8518da..f6e028b59 100644 --- a/src/com/android/launcher3/allapps/AllAppsTransitionController.java +++ b/src/com/android/launcher3/allapps/AllAppsTransitionController.java @@ -8,9 +8,11 @@ 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.DecelerateInterpolator; import android.view.animation.Interpolator; +import com.android.launcher3.pageindicators.CaretDrawable; import com.android.launcher3.DeviceProfile; import com.android.launcher3.Hotseat; import com.android.launcher3.Launcher; @@ -50,6 +52,10 @@ public class AllAppsTransitionController implements TouchController, VerticalPul private Hotseat mHotseat; private float mHotseatBackgroundAlpha; + private ObjectAnimator mCaretAnimator; + private final long mCaretAnimationDuration; + private final Interpolator mCaretInterpolator; + private float mStatusBarHeight; private final Launcher mLauncher; @@ -67,13 +73,11 @@ public class AllAppsTransitionController implements TouchController, VerticalPul private static final float DEFAULT_SHIFT_RANGE = 10; - private static final float RECATCH_REJECTION_FRACTION = .0875f; private int mBezelSwipeUpHeight; private long mAnimationDuration; - private AnimatorSet mCurrentAnimation; private boolean mNoIntercept; @@ -86,6 +90,11 @@ public class AllAppsTransitionController implements TouchController, VerticalPul mShiftCurrent = mShiftRange = DEFAULT_SHIFT_RANGE; mBezelSwipeUpHeight = launcher.getResources().getDimensionPixelSize( R.dimen.all_apps_bezel_swipe_height); + + mCaretAnimationDuration = launcher.getResources().getInteger( + R.integer.config_caretAnimationDuration); + mCaretInterpolator = AnimationUtils.loadInterpolator(launcher, + R.interpolator.caret_animation_interpolator); } @Override @@ -398,7 +407,7 @@ public class AllAppsTransitionController implements TouchController, VerticalPul if (canceled) { return; } else { - finishPullDown(); + finishPullDown(true); cleanUpAnimation(); mDetector.finishedScrolling(); } @@ -413,14 +422,21 @@ public class AllAppsTransitionController implements TouchController, VerticalPul public void finishPullUp() { mHotseat.setVisibility(View.INVISIBLE); setProgress(0f); + animateCaret(); } - public void finishPullDown() { + public void finishPullDown(boolean animated) { mAppsView.setVisibility(View.INVISIBLE); mHotseat.setBackgroundTransparent(false /* transparent */); mHotseat.setVisibility(View.VISIBLE); mAppsView.reset(); setProgress(mShiftRange); + if (animated) { + animateCaret(); + } else { + mWorkspace.getPageIndicator().getCaretDrawable() + .setLevel(CaretDrawable.LEVEL_CARET_POINTING_UP); + } } private void cancelAnimation() { @@ -435,10 +451,28 @@ public class AllAppsTransitionController implements TouchController, VerticalPul mCurrentAnimation = null; } + private void animateCaret() { + if (mCaretAnimator.isRunning()) { + mCaretAnimator.cancel(); // stop the animator in its tracks + } + + if (mLauncher.isAllAppsVisible()) { + mCaretAnimator.setIntValues(CaretDrawable.LEVEL_CARET_POINTING_DOWN); + } else { + mCaretAnimator.setIntValues(CaretDrawable.LEVEL_CARET_POINTING_UP); + } + + mCaretAnimator.start(); + } + public void setupViews(AllAppsContainerView appsView, Hotseat hotseat, Workspace workspace) { mAppsView = appsView; mHotseat = hotseat; mWorkspace = workspace; + mCaretAnimator = ObjectAnimator.ofInt(mWorkspace.getPageIndicator().getCaretDrawable(), + "level", CaretDrawable.LEVEL_CARET_POINTING_UP); // we will set values later + mCaretAnimator.setDuration(mCaretAnimationDuration); + mCaretAnimator.setInterpolator(mCaretInterpolator); mHotseat.addOnLayoutChangeListener(this); } diff --git a/src/com/android/launcher3/pageindicators/CaretDrawable.java b/src/com/android/launcher3/pageindicators/CaretDrawable.java new file mode 100644 index 000000000..3a7fc4264 --- /dev/null +++ b/src/com/android/launcher3/pageindicators/CaretDrawable.java @@ -0,0 +1,98 @@ +/* + * 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.pageindicators; + +import android.content.Context; +import android.content.res.Resources; +import android.graphics.Canvas; +import android.graphics.ColorFilter; +import android.graphics.Paint; +import android.graphics.Path; +import android.graphics.PixelFormat; + +import com.android.launcher3.R; + +import android.graphics.drawable.Drawable; + +public class CaretDrawable extends Drawable { + public static final int LEVEL_CARET_POINTING_UP = 0; // minimum possible level value + public static final int LEVEL_CARET_POINTING_DOWN = 10000; // maximum possible level value + public static final int LEVEL_CARET_NEUTRAL = LEVEL_CARET_POINTING_DOWN / 2; + + private float mCaretProgress; + + private Paint mPaint = new Paint(); + private Path mPath = new Path(); + private int mInset; + + public CaretDrawable(Context context) { + final Resources res = context.getResources(); + + mPaint.setColor(res.getColor(R.color.all_apps_caret_color)); + mPaint.setAntiAlias(true); + mPaint.setStrokeWidth(res.getDimensionPixelSize(R.dimen.all_apps_caret_stroke_width)); + mPaint.setStyle(Paint.Style.STROKE); + mPaint.setStrokeCap(Paint.Cap.SQUARE); + mPaint.setStrokeJoin(Paint.Join.MITER); + + mInset = res.getDimensionPixelSize(R.dimen.all_apps_caret_inset); + } + + @Override + public void draw(Canvas canvas) { + final float width = getBounds().width(); + final float height = getBounds().height(); + final float left = getBounds().left; + final float top = getBounds().top; + + final float verticalInset = (height / 4); + final float caretHeight = (height - (verticalInset * 2)); + + mPath.reset(); + mPath.moveTo(left, top + caretHeight * (1 - mCaretProgress)); + mPath.lineTo(left + (width / 2), top + caretHeight * mCaretProgress); + mPath.lineTo(left + width, top + caretHeight * (1 - mCaretProgress)); + + canvas.drawPath(mPath, mPaint); + } + + @Override + protected boolean onLevelChange(int level) { + mCaretProgress = (float) level / (float) LEVEL_CARET_POINTING_DOWN; + invalidateSelf(); + return true; + } + + @Override + public int getOpacity() { + return PixelFormat.OPAQUE; + } + + @Override + public void setAlpha(int alpha) { + // no-op + } + + @Override + public void setColorFilter(ColorFilter cf) { + // no-op + } + + @Override + public void setBounds(int left, int top, int right, int bottom) { + super.setBounds(left + mInset, top + mInset, right - mInset, bottom - mInset); + } +} diff --git a/src/com/android/launcher3/pageindicators/PageIndicator.java b/src/com/android/launcher3/pageindicators/PageIndicator.java index 2209bb8ad..b53715d98 100644 --- a/src/com/android/launcher3/pageindicators/PageIndicator.java +++ b/src/com/android/launcher3/pageindicators/PageIndicator.java @@ -16,6 +16,7 @@ package com.android.launcher3.pageindicators; import android.content.Context; +import android.graphics.drawable.Drawable; import android.util.AttributeSet; import android.view.View; @@ -25,6 +26,7 @@ import com.android.launcher3.dynamicui.ExtractedColors; * Base class for a page indicator. */ public abstract class PageIndicator extends View { + private CaretDrawable mCaretDrawable; protected int mNumPages = 1; @@ -45,14 +47,36 @@ public abstract class PageIndicator extends View { mNumPages--; onPageCountChanged(); } + public void setMarkersCount(int numMarkers) { mNumPages = numMarkers; onPageCountChanged(); } - protected void onPageCountChanged() { } + public CaretDrawable getCaretDrawable() { + return mCaretDrawable; + } + + public void setCaretDrawable(CaretDrawable caretDrawable) { + if (mCaretDrawable != null) { + mCaretDrawable.setCallback(null); + } + + mCaretDrawable = caretDrawable; + + if (mCaretDrawable != null) { + mCaretDrawable.setCallback(this); + } + } + + protected void onPageCountChanged() {} public void setShouldAutoHide(boolean shouldAutoHide) {} public void updateColor(ExtractedColors extractedColors) {} + + @Override + protected boolean verifyDrawable(Drawable who) { + return super.verifyDrawable(who) || who == getCaretDrawable(); + } } diff --git a/src/com/android/launcher3/pageindicators/PageIndicatorCaretLandscape.java b/src/com/android/launcher3/pageindicators/PageIndicatorCaretLandscape.java index 0f9145ddc..807520183 100644 --- a/src/com/android/launcher3/pageindicators/PageIndicatorCaretLandscape.java +++ b/src/com/android/launcher3/pageindicators/PageIndicatorCaretLandscape.java @@ -16,21 +16,16 @@ package com.android.launcher3.pageindicators; import android.content.Context; -import android.content.res.Resources; import android.graphics.Canvas; -import android.graphics.drawable.Drawable; import android.util.AttributeSet; import com.android.launcher3.Launcher; -import com.android.launcher3.R; -import com.android.launcher3.dynamicui.ExtractedColors; /** * Simply draws the caret drawable in the center. Used for the landscape layout. */ public class PageIndicatorCaretLandscape extends PageIndicator { // all apps pull up handle drawable. - private final Drawable caretDrawable; public PageIndicatorCaretLandscape(Context context) { this(context, null); @@ -43,8 +38,7 @@ public class PageIndicatorCaretLandscape extends PageIndicator { public PageIndicatorCaretLandscape(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); - Resources res = context.getResources(); - caretDrawable = res.getDrawable(R.drawable.ic_allapps_caret); + setCaretDrawable(new CaretDrawable(context)); Launcher l = (Launcher) context; setOnTouchListener(l.getHapticFeedbackTouchListener()); setOnClickListener(l); @@ -56,11 +50,11 @@ public class PageIndicatorCaretLandscape extends PageIndicator { super.onLayout(changed, left, top, right, bottom); int size = bottom - top; int l = (right - left) / 2 - size / 2; - caretDrawable.setBounds(l, 0, l + size, size); + getCaretDrawable().setBounds(l, 0, l + size, size); } @Override protected void onDraw(Canvas canvas) { - caretDrawable.draw(canvas); + getCaretDrawable().draw(canvas); } } diff --git a/src/com/android/launcher3/pageindicators/PageIndicatorLineCaret.java b/src/com/android/launcher3/pageindicators/PageIndicatorLineCaret.java index 2c157b408..4403b5a30 100644 --- a/src/com/android/launcher3/pageindicators/PageIndicatorLineCaret.java +++ b/src/com/android/launcher3/pageindicators/PageIndicatorLineCaret.java @@ -10,7 +10,6 @@ import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.Rect; -import android.graphics.drawable.Drawable; import android.os.Handler; import android.os.Looper; import android.support.v4.graphics.ColorUtils; @@ -61,8 +60,6 @@ public class PageIndicatorLineCaret extends PageIndicator { private int mTotalScroll; private Paint mLinePaint; private Launcher mLauncher; - // all apps pull up handle drawable. - private final Drawable caretDrawable; private final int mLineHeight; private final Rect mTouchHitRect = new Rect(); private final int mTouchExtensionHeight; @@ -134,7 +131,7 @@ public class PageIndicatorLineCaret extends PageIndicator { setOnClickListener(mLauncher); setOnFocusChangeListener(mLauncher.mFocusHandler); Resources res = context.getResources(); - caretDrawable = res.getDrawable(R.drawable.ic_allapps_caret); + setCaretDrawable(new CaretDrawable(context)); mLineHeight = res.getDimensionPixelSize(R.dimen.dynamic_grid_page_indicator_line_height); mTouchExtensionHeight = res.getDimensionPixelSize( R.dimen.dynamic_grid_page_indicator_extra_touch_height); @@ -145,7 +142,7 @@ public class PageIndicatorLineCaret extends PageIndicator { super.onLayout(changed, left, top, right, bottom); int size = bottom - top; int l = (right - left) / 2 - size / 2; - caretDrawable.setBounds(l, 0, l+ size, size); + getCaretDrawable().setBounds(l, 0, l + size, size); // The touch area is expanded below this view by #mTouchExtensionHeight // which extends to the top of the hotseat. @@ -159,7 +156,7 @@ public class PageIndicatorLineCaret extends PageIndicator { @Override protected void onDraw(Canvas canvas) { - caretDrawable.draw(canvas); + getCaretDrawable().draw(canvas); if (mTotalScroll == 0 || mNumPagesFloat == 0) { return; } -- 2.11.0