diff options
author | Tony Wickham <twickham@google.com> | 2016-07-15 17:23:07 -0700 |
---|---|---|
committer | Tony Wickham <twickham@google.com> | 2016-07-19 13:58:51 -0700 |
commit | 8f58e61d02fcb0ca90a2803e76a8792ec2c1f99a (patch) | |
tree | 2cba823be7962a2100c62acf086784f69fcae0fc /src/com | |
parent | 1e3d490e08b06750d467e144e5d74ea420c59613 (diff) | |
download | android_packages_apps_Trebuchet-8f58e61d02fcb0ca90a2803e76a8792ec2c1f99a.tar.gz android_packages_apps_Trebuchet-8f58e61d02fcb0ca90a2803e76a8792ec2c1f99a.tar.bz2 android_packages_apps_Trebuchet-8f58e61d02fcb0ca90a2803e76a8792ec2c1f99a.zip |
Update shortcut animations.
- Open animation: shortcuts reveal using modified circular reveal
(so that it reveals in the pill shape instead of a circle);
slight translation away from the original icon; scale icon and text.
- Hover animation: scale the shortcut pill and translate others away.
Bug: 28980830
Bug: 30127368
Change-Id: I8ed05c7a082f2c2a3f6c663da7259f6cd33e394f
Diffstat (limited to 'src/com')
9 files changed, 357 insertions, 149 deletions
diff --git a/src/com/android/launcher3/LauncherStateTransitionAnimation.java b/src/com/android/launcher3/LauncherStateTransitionAnimation.java index c3b7fe760..5c7e670a9 100644 --- a/src/com/android/launcher3/LauncherStateTransitionAnimation.java +++ b/src/com/android/launcher3/LauncherStateTransitionAnimation.java @@ -35,8 +35,8 @@ import android.view.animation.DecelerateInterpolator; import com.android.launcher3.allapps.AllAppsContainerView; import com.android.launcher3.allapps.AllAppsTransitionController; import com.android.launcher3.config.FeatureFlags; +import com.android.launcher3.util.CircleRevealOutlineProvider; import com.android.launcher3.util.Thunk; -import com.android.launcher3.util.UiThreadCircularReveal; import com.android.launcher3.widget.WidgetsContainerView; import java.util.HashMap; @@ -345,8 +345,8 @@ public class LauncherStateTransitionAnimation { float startRadius = pCb.getMaterialRevealViewStartFinalRadius(); AnimatorListenerAdapter listener = pCb.getMaterialRevealViewAnimatorListener( revealView, buttonView); - Animator reveal = UiThreadCircularReveal.createCircularReveal(revealView, width / 2, - height / 2, startRadius, revealRadius); + Animator reveal = new CircleRevealOutlineProvider(width / 2, height / 2, + startRadius, revealRadius).createRevealAnimator(revealView); reveal.setDuration(revealDuration); reveal.setInterpolator(new LogDecelerateInterpolator(100, 0)); if (listener != null) { @@ -789,8 +789,8 @@ public class LauncherStateTransitionAnimation { float finalRadius = pCb.getMaterialRevealViewStartFinalRadius(); AnimatorListenerAdapter listener = pCb.getMaterialRevealViewAnimatorListener(revealView, buttonView); - Animator reveal = UiThreadCircularReveal.createCircularReveal(revealView, width / 2, - height / 2, revealRadius, finalRadius); + Animator reveal = new CircleRevealOutlineProvider(width / 2, height / 2, + revealRadius, finalRadius).createRevealAnimator(revealView); reveal.setInterpolator(new LogDecelerateInterpolator(100, 0)); reveal.setDuration(revealDuration); reveal.setStartDelay(itemsAlphaStagger); diff --git a/src/com/android/launcher3/folder/Folder.java b/src/com/android/launcher3/folder/Folder.java index 556be0c28..2fbbad56d 100644 --- a/src/com/android/launcher3/folder/Folder.java +++ b/src/com/android/launcher3/folder/Folder.java @@ -80,8 +80,8 @@ import com.android.launcher3.logging.UserEventDispatcher.LaunchSourceProvider; import com.android.launcher3.pageindicators.PageIndicatorDots; import com.android.launcher3.userevent.nano.LauncherLogProto; import com.android.launcher3.userevent.nano.LauncherLogProto.Target; +import com.android.launcher3.util.CircleRevealOutlineProvider; import com.android.launcher3.util.Thunk; -import com.android.launcher3.util.UiThreadCircularReveal; import java.util.ArrayList; import java.util.Collections; @@ -554,8 +554,8 @@ public class Folder extends LinearLayout implements DragSource, View.OnClickList int ry = (int) Math.max(Math.max(height - getPivotY(), 0), getPivotY()); float radius = (float) Math.hypot(rx, ry); - Animator reveal = UiThreadCircularReveal.createCircularReveal(this, (int) getPivotX(), - (int) getPivotY(), 0, radius); + Animator reveal = new CircleRevealOutlineProvider((int) getPivotX(), + (int) getPivotY(), 0, radius).createRevealAnimator(this); reveal.setDuration(mMaterialExpandDuration); reveal.setInterpolator(new LogDecelerateInterpolator(100, 0)); diff --git a/src/com/android/launcher3/shortcuts/DeepShortcutView.java b/src/com/android/launcher3/shortcuts/DeepShortcutView.java index 7997d1e2e..f9dd336a2 100644 --- a/src/com/android/launcher3/shortcuts/DeepShortcutView.java +++ b/src/com/android/launcher3/shortcuts/DeepShortcutView.java @@ -16,19 +16,32 @@ package com.android.launcher3.shortcuts; +import android.animation.Animator; +import android.animation.AnimatorListenerAdapter; +import android.animation.AnimatorSet; +import android.animation.ObjectAnimator; import android.content.Context; +import android.content.res.Resources; +import android.graphics.Rect; import android.support.annotation.IntDef; import android.util.AttributeSet; +import android.view.animation.DecelerateInterpolator; +import android.widget.FrameLayout; import com.android.launcher3.BubbleTextView; +import com.android.launcher3.LauncherAnimUtils; +import com.android.launcher3.LauncherViewPropertyAnimator; import com.android.launcher3.R; +import com.android.launcher3.util.PillRevealOutlineProvider; /** - * A {@link BubbleTextView} that represents a deep shortcut within an app. + * A {@link android.widget.FrameLayout} that contains a {@link DeepShortcutView}. + * This lets us animate the DeepShortcutView (icon and text) separately from the background. */ -public class DeepShortcutView extends BubbleTextView { +public class DeepShortcutView extends FrameLayout { + + private static final float HOVER_SCALE = 1.05f; - private static final float HOVER_SCALE = 1.1f; // The direction this view should translate when animating the hover state. // This allows hovered shortcuts to "push" other shortcuts away. @IntDef({DIRECTION_UP, DIRECTION_NONE, DIRECTION_DOWN}) @@ -37,12 +50,18 @@ public class DeepShortcutView extends BubbleTextView { public static final int DIRECTION_UP = -1; public static final int DIRECTION_NONE = 0; public static final int DIRECTION_DOWN = 1; + @TranslationDirection private int mTranslationDirection = DIRECTION_NONE; private int mSpacing; + private int mRadius; + private Rect mPillRect; private int mTop; private boolean mIsHoveringOver = false; + private LauncherViewPropertyAnimator mHoverAnimator; + + private BubbleTextView mBubbleText; public DeepShortcutView(Context context) { this(context, null, 0); @@ -56,10 +75,76 @@ public class DeepShortcutView extends BubbleTextView { super(context, attrs, defStyle); mSpacing = getResources().getDimensionPixelSize(R.dimen.deep_shortcuts_spacing); + mRadius = getResources().getDimensionPixelSize(R.dimen.bg_pill_radius); + mPillRect = new Rect(); + mHoverAnimator = new LauncherViewPropertyAnimator(this); + } + + @Override + protected void onFinishInflate() { + super.onFinishInflate(); + mBubbleText = (BubbleTextView) findViewById(R.id.deep_shortcut); } - public int getSpacing() { - return mSpacing; + public BubbleTextView getBubbleText() { + return mBubbleText; + } + + @Override + protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { + super.onMeasure(widthMeasureSpec, heightMeasureSpec); + mPillRect.set(0, 0, getMeasuredWidth(), getMeasuredHeight()); + } + + @Override + public void setPivotX(float pivotX) { + super.setPivotX(pivotX); + mBubbleText.setPivotX(pivotX); + } + + @Override + public void setPivotY(float pivotY) { + super.setPivotY(pivotY); + mBubbleText.setPivotY(pivotY); + } + + /** + * Creates an animator to play when the shortcut container is being opened. + * + * @param animationIndex The index at which this animation will be started + * relative to other DeepShortcutView open animations. + */ + public Animator createOpenAnimation(int animationIndex, boolean isContainerAboveIcon) { + final Resources res = getResources(); + setVisibility(INVISIBLE); + + AnimatorSet openAnimation = LauncherAnimUtils.createAnimatorSet(); + + Animator reveal = new PillRevealOutlineProvider((int) getPivotX(), (int) getPivotY(), + mPillRect, mRadius).createRevealAnimator(this); + reveal.addListener(new AnimatorListenerAdapter() { + @Override + public void onAnimationStart(Animator animation) { + setVisibility(VISIBLE); + } + }); + + float transY = res.getDimensionPixelSize(R.dimen.deep_shortcut_anim_translation_y); + Animator translationY = ObjectAnimator.ofFloat(this, TRANSLATION_Y, + isContainerAboveIcon ? transY : -transY, 0); + + // Only scale mBubbleText (the icon and text, not the background). + mBubbleText.setScaleX(0); + mBubbleText.setScaleY(0); + LauncherViewPropertyAnimator scale = new LauncherViewPropertyAnimator(mBubbleText) + .scaleX(1).scaleY(1); + + openAnimation.playTogether(reveal, translationY, scale); + openAnimation.setStartDelay(animationIndex * res.getInteger( + R.integer.config_deepShortcutOpenStagger)); + openAnimation.setDuration(res.getInteger(R.integer.config_deepShortcutOpenDuration)); + openAnimation.setInterpolator(new DecelerateInterpolator()); + return openAnimation; } /** @@ -95,16 +180,16 @@ public class DeepShortcutView extends BubbleTextView { /** * If this shortcut is being hovered over, we scale it up. If another shortcut is being hovered * over, we translate this one away from it to account for its increased size. - * - * TODO: apply motion spec here */ private void animateHoverState() { + if (mHoverAnimator.isRunning()) { + return; + } float scale = mIsHoveringOver ? HOVER_SCALE : 1f; - setScaleX(scale); - setScaleY(scale); - - float translation = (HOVER_SCALE - 1f) * getHeight(); - setTranslationY(translation * mTranslationDirection); + float translateY = (HOVER_SCALE - 1f) * getHeight() * mTranslationDirection; + mHoverAnimator.scaleX(scale).scaleY(scale).translationY(translateY) + .setDuration(getResources().getInteger(R.integer.config_deepShortcutHoverDuration)) + .start(); } public boolean isHoveringOver() { diff --git a/src/com/android/launcher3/shortcuts/DeepShortcutsContainer.java b/src/com/android/launcher3/shortcuts/DeepShortcutsContainer.java index 70082f365..912f00622 100644 --- a/src/com/android/launcher3/shortcuts/DeepShortcutsContainer.java +++ b/src/com/android/launcher3/shortcuts/DeepShortcutsContainer.java @@ -1,6 +1,24 @@ +/* + * 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.shortcuts; import android.animation.Animator; +import android.animation.AnimatorListenerAdapter; +import android.animation.AnimatorSet; import android.annotation.TargetApi; import android.content.ComponentName; import android.content.Context; @@ -12,6 +30,7 @@ import android.os.Handler; import android.os.Looper; import android.text.TextUtils; import android.util.AttributeSet; +import android.view.LayoutInflater; import android.view.MotionEvent; import android.view.View; import android.view.ViewConfiguration; @@ -22,9 +41,9 @@ import com.android.launcher3.DragSource; import com.android.launcher3.DropTarget; import com.android.launcher3.ItemInfo; import com.android.launcher3.Launcher; +import com.android.launcher3.LauncherAnimUtils; import com.android.launcher3.LauncherAppState; import com.android.launcher3.LauncherModel; -import com.android.launcher3.LogDecelerateInterpolator; import com.android.launcher3.R; import com.android.launcher3.ShortcutInfo; import com.android.launcher3.Utilities; @@ -36,7 +55,6 @@ import com.android.launcher3.dragndrop.DragView; import com.android.launcher3.logging.UserEventDispatcher; import com.android.launcher3.userevent.nano.LauncherLogProto; import com.android.launcher3.userevent.nano.LauncherLogProto.Target; -import com.android.launcher3.util.UiThreadCircularReveal; import java.util.Collections; import java.util.Comparator; @@ -66,6 +84,7 @@ public class DeepShortcutsContainer extends LinearLayout implements View.OnLongC private Point mIconLastTouchPos = new Point(); private boolean mIsLeftAligned; private boolean mIsAboveIcon; + private boolean mIsAnimatingOpen; /** * Sorts shortcuts in rank order, with manifest shortcuts coming before dynamic shortcuts. @@ -107,11 +126,12 @@ public class DeepShortcutsContainer extends LinearLayout implements View.OnLongC public void populateAndShow(final BubbleTextView originalIcon, final List<String> ids) { // Add dummy views first, and populate with real shortcut info when ready. + final int spacing = getResources().getDimensionPixelSize(R.dimen.deep_shortcuts_spacing); + final LayoutInflater inflator = mLauncher.getLayoutInflater(); for (int i = 0; i < ids.size(); i++) { - final DeepShortcutView shortcut = (DeepShortcutView) - mLauncher.getLayoutInflater().inflate(R.layout.deep_shortcut, this, false); + final View shortcut = inflator.inflate(R.layout.deep_shortcut, this, false); if (i < ids.size() - 1) { - ((LayoutParams) shortcut.getLayoutParams()).bottomMargin = shortcut.getSpacing(); + ((LayoutParams) shortcut.getLayoutParams()).bottomMargin = spacing; } addView(shortcut); } @@ -165,7 +185,7 @@ public class DeepShortcutsContainer extends LinearLayout implements View.OnLongC @Override public void run() { - DeepShortcutView shortcutView = (DeepShortcutView) getChildAt(mShortcutChildIndex); + BubbleTextView shortcutView = getShortcutAt(mShortcutChildIndex).getBubbleText(); shortcutView.applyFromShortcutInfo(mShortcutChildInfo, LauncherAppState.getInstance().getIconCache()); shortcutView.setText(mLabel); @@ -175,19 +195,36 @@ public class DeepShortcutsContainer extends LinearLayout implements View.OnLongC } } - // TODO: update this animation + private DeepShortcutView getShortcutAt(int index) { + return (DeepShortcutView) getChildAt(index); + } + private void animateOpen(BubbleTextView originalIcon) { orientAboutIcon(originalIcon); setVisibility(View.VISIBLE); - int rx = (int) Math.max(Math.max(getMeasuredWidth() - getPivotX(), 0), getPivotX()); - int ry = (int) Math.max(Math.max(getMeasuredHeight() - getPivotY(), 0), getPivotY()); - float radius = (float) Math.hypot(rx, ry); - Animator reveal = UiThreadCircularReveal.createCircularReveal(this, (int) getPivotX(), - (int) getPivotY(), 0, radius); - reveal.setDuration(getResources().getInteger(R.integer.config_materialFolderExpandDuration)); - reveal.setInterpolator(new LogDecelerateInterpolator(100, 0)); - reveal.start(); + + final AnimatorSet shortcutAnims = LauncherAnimUtils.createAnimatorSet(); + final int numShortcuts = getChildCount(); + final int arrowOffset = getResources().getDimensionPixelSize( + R.dimen.deep_shortcuts_arrow_horizontal_offset); + final int pivotX = mIsLeftAligned ? arrowOffset : getMeasuredWidth() - arrowOffset; + final int pivotY = getShortcutAt(0).getMeasuredHeight() / 2; + for (int i = 0; i < numShortcuts; i++) { + DeepShortcutView deepShortcutView = getShortcutAt(i); + deepShortcutView.setPivotX(pivotX); + deepShortcutView.setPivotY(pivotY); + int animationIndex = mIsAboveIcon ? numShortcuts - i - 1 : i; + shortcutAnims.play(deepShortcutView.createOpenAnimation(animationIndex, mIsAboveIcon)); + } + shortcutAnims.addListener(new AnimatorListenerAdapter() { + @Override + public void onAnimationEnd(Animator animation) { + mIsAnimatingOpen = false; + } + }); + mIsAnimatingOpen = true; + shortcutAnims.start(); } /** @@ -202,7 +239,7 @@ public class DeepShortcutsContainer extends LinearLayout implements View.OnLongC * So we always align left if there is enough horizontal space * and align above if there is enough vertical space. * - * TODO: draw pointer based on orientation. + * TODO: draw arrow based on orientation. */ private void orientAboutIcon(BubbleTextView icon) { int width = getMeasuredWidth(); @@ -225,9 +262,6 @@ public class DeepShortcutsContainer extends LinearLayout implements View.OnLongC y = mTempRect.bottom; } - setPivotX(width / 2); - setPivotY(height / 2); - // Insets are added later, so subtract them now. y -= insets.top; @@ -308,8 +342,8 @@ public class DeepShortcutsContainer extends LinearLayout implements View.OnLongC } else { // Determine whether touch is over a shortcut. boolean hoveringOverShortcut = false; - for (int i = 0; i < childCount; i++) { - DeepShortcutView shortcut = (DeepShortcutView) getChildAt(i); + for (int i = 0; i < childCount && !mIsAnimatingOpen; i++) { + DeepShortcutView shortcut = getShortcutAt(i); if (shortcut.updateHoverState(containerContainsTouch, hoveringOverShortcut, y)) { hoveringOverShortcut = true; } @@ -333,9 +367,9 @@ public class DeepShortcutsContainer extends LinearLayout implements View.OnLongC cleanupDeferredDrag(); // Launch a shortcut if user was hovering over it. for (int i = 0; i < childCount; i++) { - DeepShortcutView shortcut = (DeepShortcutView) getChildAt(i); + DeepShortcutView shortcut = getShortcutAt(i); if (shortcut.isHoveringOver()) { - shortcut.performClick(); + shortcut.getBubbleText().performClick(); break; } } diff --git a/src/com/android/launcher3/util/CircleRevealOutlineProvider.java b/src/com/android/launcher3/util/CircleRevealOutlineProvider.java new file mode 100644 index 000000000..c19212019 --- /dev/null +++ b/src/com/android/launcher3/util/CircleRevealOutlineProvider.java @@ -0,0 +1,57 @@ +/* + * 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.util; + +import android.annotation.TargetApi; +import android.os.Build; + +@TargetApi(Build.VERSION_CODES.LOLLIPOP) +public class CircleRevealOutlineProvider extends RevealOutlineAnimation { + + private int mCenterX; + private int mCenterY; + private float mRadius0; + private float mRadius1; + + /** + * @param x reveal center x + * @param y reveal center y + * @param r0 initial radius + * @param r1 final radius + */ + public CircleRevealOutlineProvider(int x, int y, float r0, float r1) { + mCenterX = x; + mCenterY = y; + mRadius0 = r0; + mRadius1 = r1; + } + + @Override + public boolean shouldRemoveElevationDuringAnimation() { + return true; + } + + @Override + public void setProgress(float progress) { + mOutlineRadius = (1 - progress) * mRadius0 + progress * mRadius1; + + mOutline.left = (int) (mCenterX - mOutlineRadius); + mOutline.top = (int) (mCenterY - mOutlineRadius); + mOutline.right = (int) (mCenterX + mOutlineRadius); + mOutline.bottom = (int) (mCenterY + mOutlineRadius); + } +} diff --git a/src/com/android/launcher3/util/PillRevealOutlineProvider.java b/src/com/android/launcher3/util/PillRevealOutlineProvider.java new file mode 100644 index 000000000..09ff9bda4 --- /dev/null +++ b/src/com/android/launcher3/util/PillRevealOutlineProvider.java @@ -0,0 +1,66 @@ +/* + * 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.util; + +import android.annotation.TargetApi; +import android.graphics.Rect; +import android.os.Build; +import android.view.ViewOutlineProvider; + +@TargetApi(Build.VERSION_CODES.LOLLIPOP) +/** + * A {@link ViewOutlineProvider} that animates a reveal in a "pill" shape. + * A pill is simply a round rect, but we assume the width is greater than + * the height and that the radius is equal to half the height. + */ +public class PillRevealOutlineProvider extends RevealOutlineAnimation { + + private int mCenterX; + private int mCenterY; + private Rect mPillRect; + + /** + * @param x reveal center x + * @param y reveal center y + * @param pillRect round rect that represents the final pill shape + * @param pillRectRadius radius of the round rect + */ + public PillRevealOutlineProvider(int x, int y, Rect pillRect, float pillRectRadius) { + mCenterX = x; + mCenterY = y; + mPillRect = pillRect; + mOutlineRadius = pillRectRadius; + } + + @Override + public boolean shouldRemoveElevationDuringAnimation() { + return false; + } + + @Override + public void setProgress(float progress) { + // Assumes width is greater than height. + int centerToEdge = Math.max(mCenterX, mPillRect.width() - mCenterX); + int currentSize = (int) (progress * centerToEdge); + + // Bound the outline to the final pill shape defined by mPillRect. + mOutline.left = Math.max(mPillRect.left, mCenterX - currentSize); + mOutline.top = Math.max(mPillRect.top, mCenterY - currentSize); + mOutline.right = Math.min(mPillRect.right, mCenterX + currentSize); + mOutline.bottom = Math.min(mPillRect.bottom, mCenterY + currentSize); + } +} diff --git a/src/com/android/launcher3/util/RevealOutlineAnimation.java b/src/com/android/launcher3/util/RevealOutlineAnimation.java new file mode 100644 index 000000000..4447c3ba9 --- /dev/null +++ b/src/com/android/launcher3/util/RevealOutlineAnimation.java @@ -0,0 +1,72 @@ +package com.android.launcher3.util; + +import android.animation.Animator; +import android.animation.AnimatorListenerAdapter; +import android.animation.ValueAnimator; +import android.graphics.Outline; +import android.graphics.Rect; +import android.view.View; +import android.view.ViewOutlineProvider; + +import com.android.launcher3.Utilities; + +/** + * A {@link ViewOutlineProvider} that has helper functions to create reveal animations. + * This class should be extended so that subclasses can define the reveal shape as the + * animation progresses from 0 to 1. + */ +public abstract class RevealOutlineAnimation extends ViewOutlineProvider { + protected Rect mOutline; + protected float mOutlineRadius; + + public RevealOutlineAnimation() { + mOutline = new Rect(); + } + + /** Returns whether elevation should be removed for the duration of the reveal animation. */ + abstract boolean shouldRemoveElevationDuringAnimation(); + /** Sets the progress, from 0 to 1, of the reveal animation. */ + abstract void setProgress(float progress); + + public ValueAnimator createRevealAnimator(final View revealView) { + ValueAnimator va = ValueAnimator.ofFloat(0f, 1f); + final float elevation = revealView.getElevation(); + + va.addListener(new AnimatorListenerAdapter() { + public void onAnimationStart(Animator animation) { + revealView.setOutlineProvider(RevealOutlineAnimation.this); + revealView.setClipToOutline(true); + if (shouldRemoveElevationDuringAnimation()) { + revealView.setTranslationZ(-elevation); + } + } + + public void onAnimationEnd(Animator animation) { + revealView.setOutlineProvider(ViewOutlineProvider.BACKGROUND); + revealView.setClipToOutline(false); + if (shouldRemoveElevationDuringAnimation()) { + revealView.setTranslationZ(0); + } + } + + }); + + va.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { + @Override + public void onAnimationUpdate(ValueAnimator arg0) { + float progress = arg0.getAnimatedFraction(); + setProgress(progress); + revealView.invalidateOutline(); + if (!Utilities.ATLEAST_LOLLIPOP_MR1) { + revealView.invalidate(); + } + } + }); + return va; + } + + @Override + public void getOutline(View v, Outline outline) { + outline.setRoundRect(mOutline, mOutlineRadius); + } +} diff --git a/src/com/android/launcher3/util/RevealOutlineProvider.java b/src/com/android/launcher3/util/RevealOutlineProvider.java deleted file mode 100644 index 0db3984f8..000000000 --- a/src/com/android/launcher3/util/RevealOutlineProvider.java +++ /dev/null @@ -1,49 +0,0 @@ -package com.android.launcher3.util; - -import android.annotation.TargetApi; -import android.graphics.Outline; -import android.graphics.Rect; -import android.os.Build; -import android.view.View; -import android.view.ViewOutlineProvider; - -@TargetApi(Build.VERSION_CODES.LOLLIPOP) -public class RevealOutlineProvider extends ViewOutlineProvider { - - private int mCenterX; - private int mCenterY; - private float mRadius0; - private float mRadius1; - private int mCurrentRadius; - - private final Rect mOval; - - /** - * @param x reveal center x - * @param y reveal center y - * @param r0 initial radius - * @param r1 final radius - */ - public RevealOutlineProvider(int x, int y, float r0, float r1) { - mCenterX = x; - mCenterY = y; - mRadius0 = r0; - mRadius1 = r1; - - mOval = new Rect(); - } - - public void setProgress(float progress) { - mCurrentRadius = (int) ((1 - progress) * mRadius0 + progress * mRadius1); - - mOval.left = mCenterX - mCurrentRadius; - mOval.top = mCenterY - mCurrentRadius; - mOval.right = mCenterX + mCurrentRadius; - mOval.bottom = mCenterY + mCurrentRadius; - } - - @Override - public void getOutline(View v, Outline outline) { - outline.setRoundRect(mOval, mCurrentRadius); - } -} diff --git a/src/com/android/launcher3/util/UiThreadCircularReveal.java b/src/com/android/launcher3/util/UiThreadCircularReveal.java deleted file mode 100644 index f2b5e5e15..000000000 --- a/src/com/android/launcher3/util/UiThreadCircularReveal.java +++ /dev/null @@ -1,57 +0,0 @@ -package com.android.launcher3.util; - -import android.animation.Animator; -import android.animation.AnimatorListenerAdapter; -import android.animation.ValueAnimator; -import android.animation.ValueAnimator.AnimatorUpdateListener; -import android.annotation.TargetApi; -import android.os.Build; -import android.view.View; -import android.view.ViewOutlineProvider; - -import com.android.launcher3.Utilities; - -@TargetApi(Build.VERSION_CODES.LOLLIPOP) -public class UiThreadCircularReveal { - - public static ValueAnimator createCircularReveal(View v, int x, int y, float r0, float r1) { - return createCircularReveal(v, x, y, r0, r1, ViewOutlineProvider.BACKGROUND); - } - - public static ValueAnimator createCircularReveal(View v, int x, int y, float r0, float r1, - final ViewOutlineProvider originalProvider) { - ValueAnimator va = ValueAnimator.ofFloat(0f, 1f); - - final View revealView = v; - final RevealOutlineProvider outlineProvider = new RevealOutlineProvider(x, y, r0, r1); - final float elevation = v.getElevation(); - - va.addListener(new AnimatorListenerAdapter() { - public void onAnimationStart(Animator animation) { - revealView.setOutlineProvider(outlineProvider); - revealView.setClipToOutline(true); - revealView.setTranslationZ(-elevation); - } - - public void onAnimationEnd(Animator animation) { - revealView.setOutlineProvider(originalProvider); - revealView.setClipToOutline(false); - revealView.setTranslationZ(0); - } - - }); - - va.addUpdateListener(new AnimatorUpdateListener() { - @Override - public void onAnimationUpdate(ValueAnimator arg0) { - float progress = arg0.getAnimatedFraction(); - outlineProvider.setProgress(progress); - revealView.invalidateOutline(); - if (!Utilities.ATLEAST_LOLLIPOP_MR1) { - revealView.invalidate(); - } - } - }); - return va; - } -} |