diff options
-rw-r--r-- | res/drawable/bg_white_round_rect.xml | 21 | ||||
-rw-r--r-- | res/layout/horizontal_divider.xml | 5 | ||||
-rw-r--r-- | res/layout/notification.xml | 6 | ||||
-rw-r--r-- | res/layout/shortcuts_item.xml | 3 | ||||
-rw-r--r-- | res/values/colors.xml | 2 | ||||
-rw-r--r-- | res/values/config.xml | 7 | ||||
-rw-r--r-- | res/values/dimens.xml | 1 | ||||
-rw-r--r-- | src/com/android/launcher3/anim/PillHeightRevealOutlineProvider.java | 41 | ||||
-rw-r--r-- | src/com/android/launcher3/anim/PillRevealOutlineProvider.java | 68 | ||||
-rw-r--r-- | src/com/android/launcher3/anim/RoundedRectRevealOutlineProvider.java | 20 | ||||
-rw-r--r-- | src/com/android/launcher3/notification/NotificationItemView.java | 17 | ||||
-rw-r--r-- | src/com/android/launcher3/popup/PopupContainerWithArrow.java | 253 | ||||
-rw-r--r-- | src/com/android/launcher3/popup/PopupItemView.java | 201 | ||||
-rw-r--r-- | src/com/android/launcher3/shortcuts/ShortcutsItemView.java | 63 |
14 files changed, 225 insertions, 483 deletions
diff --git a/res/drawable/bg_white_round_rect.xml b/res/drawable/bg_white_round_rect.xml deleted file mode 100644 index c7f786ff6..000000000 --- a/res/drawable/bg_white_round_rect.xml +++ /dev/null @@ -1,21 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- Copyright (C) 2017 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. ---> - -<shape xmlns:android="http://schemas.android.com/apk/res/android" - android:shape="rectangle"> - <solid android:color="#FFFFFF" /> - <corners android:radius="@dimen/bg_round_rect_radius" /> -</shape>
\ No newline at end of file diff --git a/res/layout/horizontal_divider.xml b/res/layout/horizontal_divider.xml new file mode 100644 index 000000000..33773ebfa --- /dev/null +++ b/res/layout/horizontal_divider.xml @@ -0,0 +1,5 @@ +<?xml version="1.0" encoding="utf-8"?> +<View xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="match_parent" + android:layout_height="@dimen/popup_item_divider_height" + android:background="?android:attr/listDivider"/>
\ No newline at end of file diff --git a/res/layout/notification.xml b/res/layout/notification.xml index f955c6b80..a03dd0833 100644 --- a/res/layout/notification.xml +++ b/res/layout/notification.xml @@ -19,9 +19,7 @@ android:id="@+id/notification_view" android:layout_width="@dimen/bg_popup_item_width" android:layout_height="wrap_content" - android:elevation="@dimen/deep_shortcuts_elevation" - android:background="@drawable/bg_white_round_rect" - android:backgroundTint="@color/notification_color_beneath"> + android:elevation="@dimen/deep_shortcuts_elevation"> <RelativeLayout android:layout_width="match_parent" @@ -35,7 +33,7 @@ android:layout_height="@dimen/notification_header_height" android:paddingStart="@dimen/notification_padding_start" android:paddingEnd="@dimen/notification_padding_end" - android:background="@color/popup_header_background_color" + android:background="@color/popup_background_color" android:elevation="@dimen/notification_elevation"> <TextView android:id="@+id/notification_text" diff --git a/res/layout/shortcuts_item.xml b/res/layout/shortcuts_item.xml index 8b20bcbdc..e54462e7a 100644 --- a/res/layout/shortcuts_item.xml +++ b/res/layout/shortcuts_item.xml @@ -19,8 +19,7 @@ android:id="@+id/shortcuts_view" android:layout_width="@dimen/bg_popup_item_width" android:layout_height="wrap_content" - android:elevation="@dimen/deep_shortcuts_elevation" - android:background="@drawable/bg_white_round_rect"> + android:elevation="@dimen/deep_shortcuts_elevation"> <LinearLayout android:id="@+id/deep_shortcuts" diff --git a/res/values/colors.xml b/res/values/colors.xml index f4cd8c83e..6deffc139 100644 --- a/res/values/colors.xml +++ b/res/values/colors.xml @@ -31,7 +31,7 @@ <color name="spring_loaded_highlighted_panel_border_color">#FFF</color> <!-- Popup container --> - <color name="popup_header_background_color">#EEEEEE</color> <!-- Gray 200 --> + <color name="popup_header_background_color">#F5F5F5</color> <!-- Gray 100 --> <color name="popup_background_color">#FFF</color> <color name="notification_icon_default_color">#757575</color> <!-- Gray 600 --> <color name="notification_color_beneath">#E0E0E0</color> <!-- Gray 300 --> diff --git a/res/values/config.xml b/res/values/config.xml index 9b7c795cc..6df556b8d 100644 --- a/res/values/config.xml +++ b/res/values/config.xml @@ -124,11 +124,8 @@ <item type="id" name="preview_image_id" /> <!-- Popup items --> - <integer name="config_deepShortcutOpenDuration">220</integer> - <integer name="config_deepShortcutArrowOpenDuration">80</integer> - <integer name="config_deepShortcutOpenStagger">40</integer> - <integer name="config_deepShortcutCloseDuration">150</integer> - <integer name="config_deepShortcutCloseStagger">20</integer> + <integer name="config_popupOpenCloseDuration">220</integer> + <integer name="config_popupArrowOpenDuration">80</integer> <integer name="config_removeNotificationViewDuration">300</integer> <!-- Accessibility actions --> diff --git a/res/values/dimens.xml b/res/values/dimens.xml index 110e79042..3a531b08d 100644 --- a/res/values/dimens.xml +++ b/res/values/dimens.xml @@ -148,7 +148,6 @@ <dimen name="deep_shortcuts_elevation">9dp</dimen> <dimen name="bg_popup_item_width">220dp</dimen> <dimen name="bg_popup_item_height">56dp</dimen> - <dimen name="popup_items_spacing">4dp</dimen> <dimen name="pre_drag_view_scale">6dp</dimen> <!-- an icon with shortcuts must be dragged this far before the container is removed. --> <dimen name="deep_shortcuts_start_drag_threshold">16dp</dimen> diff --git a/src/com/android/launcher3/anim/PillHeightRevealOutlineProvider.java b/src/com/android/launcher3/anim/PillHeightRevealOutlineProvider.java deleted file mode 100644 index 679e8e32f..000000000 --- a/src/com/android/launcher3/anim/PillHeightRevealOutlineProvider.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (C) 2017 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.anim; - -import android.graphics.Rect; - -/** - * Extension of {@link PillRevealOutlineProvider} which only changes the height of the pill. - * For now, we assume the height is added/removed from the bottom. - */ -public class PillHeightRevealOutlineProvider extends PillRevealOutlineProvider { - - private final int mNewHeight; - - public PillHeightRevealOutlineProvider(Rect pillRect, float radius, int newHeight) { - super(0, 0, pillRect, radius); - mOutline.set(pillRect); - mNewHeight = newHeight; - } - - @Override - public void setProgress(float progress) { - mOutline.top = 0; - int heightDifference = mPillRect.height() - mNewHeight; - mOutline.bottom = (int) (mPillRect.bottom - heightDifference * (1 - progress)); - } -} diff --git a/src/com/android/launcher3/anim/PillRevealOutlineProvider.java b/src/com/android/launcher3/anim/PillRevealOutlineProvider.java deleted file mode 100644 index 450f9db9a..000000000 --- a/src/com/android/launcher3/anim/PillRevealOutlineProvider.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * 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.anim; - -import android.graphics.Rect; -import android.view.ViewOutlineProvider; - -/** - * 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 float mFinalRadius; - protected Rect mPillRect; - - /** - * @param x reveal center x - * @param y reveal center y - * @param pillRect round rect that represents the final pill shape - */ - public PillRevealOutlineProvider(int x, int y, Rect pillRect) { - this(x, y, pillRect, pillRect.height() / 2f); - } - - public PillRevealOutlineProvider(int x, int y, Rect pillRect, float radius) { - mCenterX = x; - mCenterY = y; - mPillRect = pillRect; - mOutlineRadius = mFinalRadius = radius; - } - - @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); - mOutlineRadius = Math.min(mFinalRadius, mOutline.height() / 2); - } -} diff --git a/src/com/android/launcher3/anim/RoundedRectRevealOutlineProvider.java b/src/com/android/launcher3/anim/RoundedRectRevealOutlineProvider.java index 9c09477bb..d01b26c8f 100644 --- a/src/com/android/launcher3/anim/RoundedRectRevealOutlineProvider.java +++ b/src/com/android/launcher3/anim/RoundedRectRevealOutlineProvider.java @@ -18,6 +18,11 @@ package com.android.launcher3.anim; import android.graphics.Rect; +import com.android.launcher3.popup.PopupContainerWithArrow; + +import static com.android.launcher3.popup.PopupContainerWithArrow.ROUNDED_BOTTOM_CORNERS; +import static com.android.launcher3.popup.PopupContainerWithArrow.ROUNDED_TOP_CORNERS; + /** * A {@link RevealOutlineAnimation} that provides an outline that interpolates between two radii * and two {@link Rect}s. @@ -32,12 +37,21 @@ public class RoundedRectRevealOutlineProvider extends RevealOutlineAnimation { private final Rect mStartRect; private final Rect mEndRect; + private final @PopupContainerWithArrow.RoundedCornerFlags int mRoundedCorners; + public RoundedRectRevealOutlineProvider(float startRadius, float endRadius, Rect startRect, Rect endRect) { + this(startRadius, endRadius, startRect, endRect, + ROUNDED_TOP_CORNERS | ROUNDED_BOTTOM_CORNERS); + } + + public RoundedRectRevealOutlineProvider(float startRadius, float endRadius, Rect startRect, + Rect endRect, int roundedCorners) { mStartRadius = startRadius; mEndRadius = endRadius; mStartRect = startRect; mEndRect = endRect; + mRoundedCorners = roundedCorners; } @Override @@ -51,7 +65,13 @@ public class RoundedRectRevealOutlineProvider extends RevealOutlineAnimation { mOutline.left = (int) ((1 - progress) * mStartRect.left + progress * mEndRect.left); mOutline.top = (int) ((1 - progress) * mStartRect.top + progress * mEndRect.top); + if ((mRoundedCorners & ROUNDED_TOP_CORNERS) == 0) { + mOutline.top -= mOutlineRadius; + } mOutline.right = (int) ((1 - progress) * mStartRect.right + progress * mEndRect.right); mOutline.bottom = (int) ((1 - progress) * mStartRect.bottom + progress * mEndRect.bottom); + if ((mRoundedCorners & ROUNDED_BOTTOM_CORNERS) == 0) { + mOutline.bottom += mOutlineRadius; + } } } diff --git a/src/com/android/launcher3/notification/NotificationItemView.java b/src/com/android/launcher3/notification/NotificationItemView.java index 997def277..416d546ea 100644 --- a/src/com/android/launcher3/notification/NotificationItemView.java +++ b/src/com/android/launcher3/notification/NotificationItemView.java @@ -21,7 +21,6 @@ import android.app.Notification; import android.content.Context; import android.graphics.Rect; import android.support.annotation.Nullable; -import android.support.v4.content.ContextCompat; import android.util.AttributeSet; import android.view.MotionEvent; import android.view.View; @@ -30,7 +29,7 @@ import android.widget.TextView; import com.android.launcher3.ItemInfo; import com.android.launcher3.R; -import com.android.launcher3.anim.PillHeightRevealOutlineProvider; +import com.android.launcher3.anim.RoundedRectRevealOutlineProvider; import com.android.launcher3.graphics.IconPalette; import com.android.launcher3.logging.UserEventDispatcher.LogContainerProvider; import com.android.launcher3.popup.PopupItemView; @@ -87,9 +86,10 @@ public class NotificationItemView extends PopupItemView implements LogContainerP } public Animator animateHeightRemoval(int heightToRemove) { - final int newHeight = getHeight() - heightToRemove; - return new PillHeightRevealOutlineProvider(mPillRect, - getBackgroundRadius(), newHeight).createRevealAnimator(this, true /* isReversed */); + Rect endRect = new Rect(mPillRect); + endRect.bottom -= heightToRemove; + return new RoundedRectRevealOutlineProvider(getBackgroundRadius(), getBackgroundRadius(), + mPillRect, endRect, mRoundedCorners).createRevealAnimator(this, false); } public void updateHeader(int notificationCount, @Nullable IconPalette palette) { @@ -163,13 +163,6 @@ public class NotificationItemView extends PopupItemView implements LogContainerP } @Override - public int getArrowColor(boolean isArrowAttachedToBottom) { - return ContextCompat.getColor(getContext(), isArrowAttachedToBottom - ? R.color.popup_background_color - : R.color.popup_header_background_color); - } - - @Override public void fillInLogContainerData(View v, ItemInfo info, LauncherLogProto.Target target, LauncherLogProto.Target targetParent) { target.itemType = LauncherLogProto.ItemType.NOTIFICATION; diff --git a/src/com/android/launcher3/popup/PopupContainerWithArrow.java b/src/com/android/launcher3/popup/PopupContainerWithArrow.java index b373a1766..152886e81 100644 --- a/src/com/android/launcher3/popup/PopupContainerWithArrow.java +++ b/src/com/android/launcher3/popup/PopupContainerWithArrow.java @@ -20,19 +20,22 @@ import android.animation.Animator; import android.animation.AnimatorListenerAdapter; import android.animation.AnimatorSet; import android.animation.ObjectAnimator; -import android.animation.TimeInterpolator; import android.animation.ValueAnimator; import android.annotation.TargetApi; import android.content.Context; import android.content.res.Resources; import android.graphics.CornerPathEffect; +import android.graphics.Outline; import android.graphics.Paint; +import android.graphics.Point; import android.graphics.PointF; import android.graphics.Rect; import android.graphics.drawable.ShapeDrawable; import android.os.Build; import android.os.Handler; import android.os.Looper; +import android.support.annotation.IntDef; +import android.support.v4.content.ContextCompat; import android.util.AttributeSet; import android.view.Gravity; import android.view.LayoutInflater; @@ -40,7 +43,7 @@ import android.view.MotionEvent; import android.view.View; import android.view.ViewConfiguration; import android.view.accessibility.AccessibilityEvent; -import android.view.animation.DecelerateInterpolator; +import android.view.animation.AccelerateDecelerateInterpolator; import android.widget.FrameLayout; import com.android.launcher3.AbstractFloatingView; @@ -53,13 +56,13 @@ import com.android.launcher3.Launcher; import com.android.launcher3.LauncherAnimUtils; import com.android.launcher3.LauncherModel; import com.android.launcher3.LauncherSettings; -import com.android.launcher3.LogAccelerateInterpolator; import com.android.launcher3.R; import com.android.launcher3.Utilities; import com.android.launcher3.accessibility.LauncherAccessibilityDelegate; import com.android.launcher3.accessibility.ShortcutMenuAccessibilityDelegate; import com.android.launcher3.anim.PropertyListBuilder; import com.android.launcher3.anim.PropertyResetListener; +import com.android.launcher3.anim.RoundedRectRevealOutlineProvider; import com.android.launcher3.badge.BadgeInfo; import com.android.launcher3.dragndrop.DragController; import com.android.launcher3.dragndrop.DragLayer; @@ -73,6 +76,8 @@ import com.android.launcher3.shortcuts.DeepShortcutView; import com.android.launcher3.shortcuts.ShortcutsItemView; import com.android.launcher3.util.PackageUserKey; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; import java.util.Collections; import java.util.List; import java.util.Map; @@ -89,6 +94,16 @@ import static com.android.launcher3.userevent.nano.LauncherLogProto.Target; public class PopupContainerWithArrow extends AbstractFloatingView implements DragSource, DragController.DragListener { + public static final int ROUNDED_TOP_CORNERS = 1 << 0; + public static final int ROUNDED_BOTTOM_CORNERS = 1 << 1; + + @IntDef(flag = true, value = { + ROUNDED_TOP_CORNERS, + ROUNDED_BOTTOM_CORNERS + }) + @Retention(RetentionPolicy.SOURCE) + public @interface RoundedCornerFlags {} + protected final Launcher mLauncher; private final int mStartDragThreshold; private LauncherAccessibilityDelegate mAccessibilityDelegate; @@ -107,6 +122,8 @@ public class PopupContainerWithArrow extends AbstractFloatingView implements Dra protected Animator mOpenCloseAnimator; private boolean mDeferContainerRemoval; private AnimatorSet mReduceHeightAnimatorSet; + private final Rect mStartRect = new Rect(); + private final Rect mEndRect = new Rect(); public PopupContainerWithArrow(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); @@ -222,6 +239,7 @@ public class PopupContainerWithArrow extends AbstractFloatingView implements Dra mArrow.setPivotX(arrowWidth / 2); mArrow.setPivotY(mIsAboveIcon ? 0 : arrowHeight); + measure(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED); animateOpen(); mLauncher.getDragController().addDragListener(this); @@ -238,46 +256,66 @@ public class PopupContainerWithArrow extends AbstractFloatingView implements Dra private void addDummyViews(PopupPopulator.Item[] itemTypesToPopulate, boolean notificationFooterHasIcons) { final Resources res = getResources(); - final int spacing = res.getDimensionPixelSize(R.dimen.popup_items_spacing); final LayoutInflater inflater = mLauncher.getLayoutInflater(); + int shortcutsItemRoundedCorners = ROUNDED_TOP_CORNERS | ROUNDED_BOTTOM_CORNERS; int numItems = itemTypesToPopulate.length; for (int i = 0; i < numItems; i++) { PopupPopulator.Item itemTypeToPopulate = itemTypesToPopulate[i]; + PopupPopulator.Item prevItemTypeToPopulate = + i > 0 ? itemTypesToPopulate[i - 1] : null; PopupPopulator.Item nextItemTypeToPopulate = i < numItems - 1 ? itemTypesToPopulate[i + 1] : null; final View item = inflater.inflate(itemTypeToPopulate.layoutId, this, false); + boolean shouldUnroundTopCorners = prevItemTypeToPopulate != null + && itemTypeToPopulate.isShortcut ^ prevItemTypeToPopulate.isShortcut; + boolean shouldUnroundBottomCorners = nextItemTypeToPopulate != null + && itemTypeToPopulate.isShortcut ^ nextItemTypeToPopulate.isShortcut; + if (itemTypeToPopulate == PopupPopulator.Item.NOTIFICATION) { mNotificationItemView = (NotificationItemView) item; int footerHeight = notificationFooterHasIcons ? res.getDimensionPixelSize(R.dimen.notification_footer_height) : 0; item.findViewById(R.id.footer).getLayoutParams().height = footerHeight; + + int roundedCorners = ROUNDED_TOP_CORNERS | ROUNDED_BOTTOM_CORNERS; + if (shouldUnroundTopCorners) { + roundedCorners &= ~ROUNDED_TOP_CORNERS; + } + if (shouldUnroundBottomCorners) { + roundedCorners &= ~ROUNDED_BOTTOM_CORNERS; + } + int backgroundColor = ContextCompat.getColor(getContext(), + R.color.notification_color_beneath); + mNotificationItemView.setBackgroundWithCorners(backgroundColor, roundedCorners); + mNotificationItemView.getMainView().setAccessibilityDelegate(mAccessibilityDelegate); } else if (itemTypeToPopulate == PopupPopulator.Item.SHORTCUT) { item.setAccessibilityDelegate(mAccessibilityDelegate); } - boolean shouldAddBottomMargin = nextItemTypeToPopulate != null - && itemTypeToPopulate.isShortcut ^ nextItemTypeToPopulate.isShortcut; - if (itemTypeToPopulate.isShortcut) { if (mShortcutsItemView == null) { mShortcutsItemView = (ShortcutsItemView) inflater.inflate( R.layout.shortcuts_item, this, false); addView(mShortcutsItemView); + if (shouldUnroundTopCorners) { + shortcutsItemRoundedCorners &= ~ROUNDED_TOP_CORNERS; + } } mShortcutsItemView.addShortcutView(item, itemTypeToPopulate); - if (shouldAddBottomMargin) { - ((LayoutParams) mShortcutsItemView.getLayoutParams()).bottomMargin = spacing; + if (shouldUnroundBottomCorners) { + shortcutsItemRoundedCorners &= ~ROUNDED_BOTTOM_CORNERS; } } else { addView(item); - if (shouldAddBottomMargin) { - ((LayoutParams) item.getLayoutParams()).bottomMargin = spacing; - } } } + int backgroundColor = ContextCompat.getColor(getContext(), mNotificationItemView == null + ? R.color.popup_background_color + : R.color.popup_header_background_color); + mShortcutsItemView.setBackgroundWithCorners(backgroundColor, shortcutsItemRoundedCorners); } protected PopupItemView getItemViewAt(int index) { @@ -297,45 +335,31 @@ public class PopupContainerWithArrow extends AbstractFloatingView implements Dra setVisibility(View.VISIBLE); mIsOpen = true; - final AnimatorSet shortcutAnims = LauncherAnimUtils.createAnimatorSet(); - final int itemCount = getItemCount(); - - final long duration = getResources().getInteger( - R.integer.config_deepShortcutOpenDuration); - final long arrowScaleDuration = getResources().getInteger( - R.integer.config_deepShortcutArrowOpenDuration); - final long arrowScaleDelay = duration - arrowScaleDuration; - final long stagger = getResources().getInteger( - R.integer.config_deepShortcutOpenStagger); - final TimeInterpolator fadeInterpolator = new LogAccelerateInterpolator(100, 0); - - // Animate shortcuts - DecelerateInterpolator interpolator = new DecelerateInterpolator(); - for (int i = 0; i < itemCount; i++) { - final PopupItemView popupItemView = getItemViewAt(i); - popupItemView.setVisibility(INVISIBLE); - popupItemView.setAlpha(0); - - Animator anim = popupItemView.createOpenAnimation(mIsAboveIcon, mIsLeftAligned); - anim.addListener(new AnimatorListenerAdapter() { - @Override - public void onAnimationStart(Animator animation) { - popupItemView.setVisibility(VISIBLE); - } - }); - anim.setDuration(duration); - int animationIndex = mIsAboveIcon ? itemCount - i - 1 : i; - anim.setStartDelay(stagger * animationIndex); - anim.setInterpolator(interpolator); - shortcutAnims.play(anim); - - Animator fadeAnim = ObjectAnimator.ofFloat(popupItemView, View.ALPHA, 1); - fadeAnim.setInterpolator(fadeInterpolator); - // We want the shortcut to be fully opaque before the arrow starts animating. - fadeAnim.setDuration(arrowScaleDelay); - shortcutAnims.play(fadeAnim); - } - shortcutAnims.addListener(new AnimatorListenerAdapter() { + final AnimatorSet openAnim = LauncherAnimUtils.createAnimatorSet(); + final Resources res = getResources(); + + // Rectangular reveal. + int itemsTotalHeight = 0; + for (int i = 0; i < getItemCount(); i++) { + itemsTotalHeight += getItemViewAt(i).getMeasuredHeight(); + } + Point startPoint = computeAnimStartPoint(itemsTotalHeight); + int top = mIsAboveIcon ? getPaddingTop() : startPoint.y; + float radius = getItemViewAt(0).getBackgroundRadius(); + mStartRect.set(startPoint.x, startPoint.y, startPoint.x, startPoint.y); + mEndRect.set(0, top, getMeasuredWidth(), top + itemsTotalHeight); + final ValueAnimator revealAnim = new RoundedRectRevealOutlineProvider + (radius, radius, mStartRect, mEndRect).createRevealAnimator(this, false); + revealAnim.setDuration((long) res.getInteger(R.integer.config_popupOpenCloseDuration)); + revealAnim.setInterpolator(new AccelerateDecelerateInterpolator()); + + // Animate the arrow. + mArrow.setScaleX(0); + mArrow.setScaleY(0); + Animator arrowScale = createArrowScaleAnim(1).setDuration(res.getInteger( + R.integer.config_popupArrowOpenDuration)); + + openAnim.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { mOpenCloseAnimator = null; @@ -346,15 +370,26 @@ public class PopupContainerWithArrow extends AbstractFloatingView implements Dra } }); - // Animate the arrow - mArrow.setScaleX(0); - mArrow.setScaleY(0); - Animator arrowScale = createArrowScaleAnim(1).setDuration(arrowScaleDuration); - arrowScale.setStartDelay(arrowScaleDelay); - shortcutAnims.play(arrowScale); + mOpenCloseAnimator = openAnim; + openAnim.playSequentially(revealAnim, arrowScale); + openAnim.start(); + } - mOpenCloseAnimator = shortcutAnims; - shortcutAnims.start(); + /** + * Returns the point at which the center of the arrow merges with the first popup item. + */ + private Point computeAnimStartPoint(int itemsTotalHeight) { + int arrowCenterX = getResources().getDimensionPixelSize(mIsLeftAligned ^ mIsRtl ? + R.dimen.popup_arrow_horizontal_center_start: + R.dimen.popup_arrow_horizontal_center_end); + if (!mIsLeftAligned) { + arrowCenterX = getMeasuredWidth() - arrowCenterX; + } + int arrowHeight = getMeasuredHeight() - getPaddingTop() - getPaddingBottom() + - itemsTotalHeight; + // The y-coordinate of edge between the arrow and the first popup item. + int arrowEdge = getPaddingTop() + (mIsAboveIcon ? itemsTotalHeight : arrowHeight); + return new Point(arrowCenterX, arrowEdge); } /** @@ -506,7 +541,7 @@ public class PopupContainerWithArrow extends AbstractFloatingView implements Dra // since the latter expects the arrow which hasn't been added yet. PopupItemView itemAttachedToArrow = (PopupItemView) (getChildAt(mIsAboveIcon ? getChildCount() - 1 : 0)); - arrowPaint.setColor(itemAttachedToArrow.getArrowColor(mIsAboveIcon)); + arrowPaint.setColor(ContextCompat.getColor(mLauncher, R.color.popup_background_color)); // The corner path effect won't be reflected in the shadow, but shouldn't be noticeable. int radius = getResources().getDimensionPixelSize(R.dimen.popup_arrow_corner_radius); arrowPaint.setPathEffect(new CornerPathEffect(radius)); @@ -609,22 +644,8 @@ public class PopupContainerWithArrow extends AbstractFloatingView implements Dra AnimatorSet removeNotification = LauncherAnimUtils.createAnimatorSet(); final int duration = getResources().getInteger( R.integer.config_removeNotificationViewDuration); - final int spacing = getResources().getDimensionPixelSize(R.dimen.popup_items_spacing); removeNotification.play(reduceNotificationViewHeight( - mNotificationItemView.getHeightMinusFooter() + spacing, duration)); - final View removeMarginView = mIsAboveIcon ? getItemViewAt(getItemCount() - 2) - : mNotificationItemView; - if (removeMarginView != null) { - ValueAnimator removeMargin = ValueAnimator.ofFloat(1, 0).setDuration(duration); - removeMargin.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { - @Override - public void onAnimationUpdate(ValueAnimator valueAnimator) { - ((MarginLayoutParams) removeMarginView.getLayoutParams()).bottomMargin - = (int) (spacing * (float) valueAnimator.getAnimatedValue()); - } - }); - removeNotification.play(removeMargin); - } + mNotificationItemView.getHeightMinusFooter(), duration)); Animator fade = ObjectAnimator.ofFloat(mNotificationItemView, ALPHA, 0) .setDuration(duration); fade.addListener(new AnimatorListenerAdapter() { @@ -634,19 +655,25 @@ public class PopupContainerWithArrow extends AbstractFloatingView implements Dra mNotificationItemView = null; if (getItemCount() == 0) { close(false); - return; } } }); removeNotification.play(fade); final long arrowScaleDuration = getResources().getInteger( - R.integer.config_deepShortcutArrowOpenDuration); + R.integer.config_popupArrowOpenDuration); Animator hideArrow = createArrowScaleAnim(0).setDuration(arrowScaleDuration); hideArrow.setStartDelay(0); Animator showArrow = createArrowScaleAnim(1).setDuration(arrowScaleDuration); showArrow.setStartDelay((long) (duration - arrowScaleDuration * 1.5)); removeNotification.playSequentially(hideArrow, showArrow); removeNotification.start(); + if (mShortcutsItemView != null) { + int backgroundColor = ContextCompat.getColor(getContext(), + R.color.popup_background_color); + // With notifications gone, all corners of shortcuts item should be rounded. + mShortcutsItemView.setBackgroundWithCorners(backgroundColor, + ROUNDED_TOP_CORNERS | ROUNDED_BOTTOM_CORNERS); + } return; } mNotificationItemView.trimNotifications(NotificationKeyData.extractKeysOnly( @@ -770,55 +797,40 @@ public class PopupContainerWithArrow extends AbstractFloatingView implements Dra if (!mIsOpen) { return; } + mEndRect.setEmpty(); if (mOpenCloseAnimator != null) { + Outline outline = new Outline(); + getOutlineProvider().getOutline(this, outline); + outline.getRect(mEndRect); mOpenCloseAnimator.cancel(); } mIsOpen = false; - final AnimatorSet shortcutAnims = LauncherAnimUtils.createAnimatorSet(); - final int itemCount = getItemCount(); - int numOpenShortcuts = 0; - for (int i = 0; i < itemCount; i++) { - if (getItemViewAt(i).isOpenOrOpening()) { - numOpenShortcuts++; - } + final AnimatorSet closeAnim = LauncherAnimUtils.createAnimatorSet(); + final Resources res = getResources(); + + // Animate the arrow. + Animator arrowScale = createArrowScaleAnim(0).setDuration(res.getInteger( + R.integer.config_popupArrowOpenDuration)); + + // Rectangular reveal (reversed). + int itemsTotalHeight = 0; + for (int i = 0; i < getItemCount(); i++) { + itemsTotalHeight += getItemViewAt(i).getMeasuredHeight(); } - final long duration = getResources().getInteger( - R.integer.config_deepShortcutCloseDuration); - final long arrowScaleDuration = getResources().getInteger( - R.integer.config_deepShortcutArrowOpenDuration); - final long stagger = getResources().getInteger( - R.integer.config_deepShortcutCloseStagger); - final TimeInterpolator fadeInterpolator = new LogAccelerateInterpolator(100, 0); - - int firstOpenItemIndex = mIsAboveIcon ? itemCount - numOpenShortcuts : 0; - for (int i = firstOpenItemIndex; i < firstOpenItemIndex + numOpenShortcuts; i++) { - final PopupItemView view = getItemViewAt(i); - Animator anim; - anim = view.createCloseAnimation(mIsAboveIcon, mIsLeftAligned, duration); - int animationIndex = mIsAboveIcon ? i - firstOpenItemIndex - : numOpenShortcuts - i - 1; - anim.setStartDelay(stagger * animationIndex); - - Animator fadeAnim = ObjectAnimator.ofFloat(view, View.ALPHA, 0); - // Don't start fading until the arrow is gone. - fadeAnim.setStartDelay(stagger * animationIndex + arrowScaleDuration); - fadeAnim.setDuration(duration - arrowScaleDuration); - fadeAnim.setInterpolator(fadeInterpolator); - shortcutAnims.play(fadeAnim); - anim.addListener(new AnimatorListenerAdapter() { - @Override - public void onAnimationEnd(Animator animation) { - view.setVisibility(INVISIBLE); - } - }); - shortcutAnims.play(anim); + Point startPoint = computeAnimStartPoint(itemsTotalHeight); + int top = mIsAboveIcon ? getPaddingTop() : startPoint.y; + float radius = getItemViewAt(0).getBackgroundRadius(); + mStartRect.set(startPoint.x, startPoint.y, startPoint.x, startPoint.y); + if (mEndRect.isEmpty()) { + mEndRect.set(0, top, getMeasuredWidth(), top + itemsTotalHeight); } - Animator arrowAnim = createArrowScaleAnim(0).setDuration(arrowScaleDuration); - arrowAnim.setStartDelay(0); - shortcutAnims.play(arrowAnim); + final ValueAnimator revealAnim = new RoundedRectRevealOutlineProvider( + radius, radius, mStartRect, mEndRect).createRevealAnimator(this, true); + revealAnim.setDuration((long) res.getInteger(R.integer.config_popupOpenCloseDuration)); + revealAnim.setInterpolator(new AccelerateDecelerateInterpolator()); - shortcutAnims.addListener(new AnimatorListenerAdapter() { + closeAnim.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { mOpenCloseAnimator = null; @@ -829,8 +841,9 @@ public class PopupContainerWithArrow extends AbstractFloatingView implements Dra } } }); - mOpenCloseAnimator = shortcutAnims; - shortcutAnims.start(); + mOpenCloseAnimator = closeAnim; + closeAnim.playSequentially(arrowScale, revealAnim); + closeAnim.start(); mOriginalIcon.forceHideBadge(false); } diff --git a/src/com/android/launcher3/popup/PopupItemView.java b/src/com/android/launcher3/popup/PopupItemView.java index b073defa4..05cadb671 100644 --- a/src/com/android/launcher3/popup/PopupItemView.java +++ b/src/com/android/launcher3/popup/PopupItemView.java @@ -16,38 +16,34 @@ package com.android.launcher3.popup; -import android.animation.Animator; -import android.animation.AnimatorListenerAdapter; -import android.animation.ValueAnimator; import android.content.Context; import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Matrix; import android.graphics.Paint; -import android.graphics.Point; import android.graphics.PorterDuff; import android.graphics.PorterDuffXfermode; import android.graphics.Rect; +import android.graphics.drawable.ShapeDrawable; +import android.graphics.drawable.shapes.RoundRectShape; import android.util.AttributeSet; import android.view.View; import android.widget.FrameLayout; -import com.android.launcher3.LogAccelerateInterpolator; import com.android.launcher3.R; import com.android.launcher3.Utilities; -import com.android.launcher3.anim.PillRevealOutlineProvider; +import com.android.launcher3.popup.PopupContainerWithArrow.RoundedCornerFlags; + +import static com.android.launcher3.popup.PopupContainerWithArrow.ROUNDED_BOTTOM_CORNERS; +import static com.android.launcher3.popup.PopupContainerWithArrow.ROUNDED_TOP_CORNERS; /** - * An abstract {@link FrameLayout} that supports animating an item's content - * (e.g. icon and text) separate from the item's background. + * An abstract {@link FrameLayout} that contains content for {@link PopupContainerWithArrow}. */ -public abstract class PopupItemView extends FrameLayout - implements ValueAnimator.AnimatorUpdateListener { - - protected static final Point sTempPoint = new Point(); +public abstract class PopupItemView extends FrameLayout { protected final Rect mPillRect; - private float mOpenAnimationProgress; + protected @RoundedCornerFlags int mRoundedCorners; protected final boolean mIsRtl; protected View mIconView; @@ -93,164 +89,55 @@ public abstract class PopupItemView extends FrameLayout @Override protected void dispatchDraw(Canvas canvas) { + if (mRoundedCorners == 0) { + super.dispatchDraw(canvas); + return; + } + int saveCount = canvas.saveLayer(0, 0, getWidth(), getHeight(), null); super.dispatchDraw(canvas); + // Clip children to this item's rounded corners. int cornerWidth = mRoundedCornerBitmap.getWidth(); int cornerHeight = mRoundedCornerBitmap.getHeight(); - // Clip top left corner. - mMatrix.reset(); - canvas.drawBitmap(mRoundedCornerBitmap, mMatrix, mBackgroundClipPaint); - // Clip top right corner. - mMatrix.setRotate(90, cornerWidth / 2, cornerHeight / 2); - mMatrix.postTranslate(canvas.getWidth() - cornerWidth, 0); - canvas.drawBitmap(mRoundedCornerBitmap, mMatrix, mBackgroundClipPaint); - // Clip bottom right corner. - mMatrix.setRotate(180, cornerWidth / 2, cornerHeight / 2); - mMatrix.postTranslate(canvas.getWidth() - cornerWidth, canvas.getHeight() - cornerHeight); - canvas.drawBitmap(mRoundedCornerBitmap, mMatrix, mBackgroundClipPaint); - // Clip bottom left corner. - mMatrix.setRotate(270, cornerWidth / 2, cornerHeight / 2); - mMatrix.postTranslate(0, canvas.getHeight() - cornerHeight); - canvas.drawBitmap(mRoundedCornerBitmap, mMatrix, mBackgroundClipPaint); + if ((mRoundedCorners & ROUNDED_TOP_CORNERS) != 0) { + // Clip top left corner. + mMatrix.reset(); + canvas.drawBitmap(mRoundedCornerBitmap, mMatrix, mBackgroundClipPaint); + // Clip top right corner. + mMatrix.setRotate(90, cornerWidth / 2, cornerHeight / 2); + mMatrix.postTranslate(canvas.getWidth() - cornerWidth, 0); + canvas.drawBitmap(mRoundedCornerBitmap, mMatrix, mBackgroundClipPaint); + } + if ((mRoundedCorners & ROUNDED_BOTTOM_CORNERS) != 0) { + // Clip bottom right corner. + mMatrix.setRotate(180, cornerWidth / 2, cornerHeight / 2); + mMatrix.postTranslate(canvas.getWidth() - cornerWidth, canvas.getHeight() - cornerHeight); + canvas.drawBitmap(mRoundedCornerBitmap, mMatrix, mBackgroundClipPaint); + // Clip bottom left corner. + mMatrix.setRotate(270, cornerWidth / 2, cornerHeight / 2); + mMatrix.postTranslate(0, canvas.getHeight() - cornerHeight); + canvas.drawBitmap(mRoundedCornerBitmap, mMatrix, mBackgroundClipPaint); + } canvas.restoreToCount(saveCount); } /** - * Creates an animator to play when the shortcut container is being opened. + * Creates a round rect drawable (with the specified corners unrounded) + * and sets it as this View's background. */ - public Animator createOpenAnimation(boolean isContainerAboveIcon, boolean pivotLeft) { - Point center = getIconCenter(); - int arrowCenter = getResources().getDimensionPixelSize(pivotLeft ^ mIsRtl ? - R.dimen.popup_arrow_horizontal_center_start: - R.dimen.popup_arrow_horizontal_center_end); - ValueAnimator openAnimator = new ZoomRevealOutlineProvider(center.x, center.y, - mPillRect, this, mIconView, isContainerAboveIcon, pivotLeft, arrowCenter) - .createRevealAnimator(this, false); - mOpenAnimationProgress = 0f; - openAnimator.addUpdateListener(this); - return openAnimator; - } - - @Override - public void onAnimationUpdate(ValueAnimator valueAnimator) { - mOpenAnimationProgress = valueAnimator.getAnimatedFraction(); - } - - public boolean isOpenOrOpening() { - return mOpenAnimationProgress > 0; - } - - /** - * Creates an animator to play when the shortcut container is being closed. - */ - public Animator createCloseAnimation(boolean isContainerAboveIcon, boolean pivotLeft, - long duration) { - Point center = getIconCenter(); - int arrowCenter = getResources().getDimensionPixelSize(pivotLeft ^ mIsRtl ? - R.dimen.popup_arrow_horizontal_center_start : - R.dimen.popup_arrow_horizontal_center_end); - ValueAnimator closeAnimator = new ZoomRevealOutlineProvider(center.x, center.y, - mPillRect, this, mIconView, isContainerAboveIcon, pivotLeft, arrowCenter) - .createRevealAnimator(this, true); - // Scale down the duration and interpolator according to the progress - // that the open animation was at when the close started. - closeAnimator.setDuration((long) (duration * mOpenAnimationProgress)); - closeAnimator.setInterpolator(new CloseInterpolator(mOpenAnimationProgress)); - closeAnimator.addListener(new AnimatorListenerAdapter() { - @Override - public void onAnimationEnd(Animator animation) { - mOpenAnimationProgress = 0; - } - }); - return closeAnimator; - } - - /** - * Returns the position of the center of the icon relative to the container. - */ - public Point getIconCenter() { - sTempPoint.y = getMeasuredHeight() / 2; - sTempPoint.x = getResources().getDimensionPixelSize(R.dimen.bg_popup_item_height) / 2; - if (Utilities.isRtl(getResources())) { - sTempPoint.x = getMeasuredWidth() - sTempPoint.x; - } - return sTempPoint; + public void setBackgroundWithCorners(int color, @RoundedCornerFlags int roundedCorners) { + mRoundedCorners = roundedCorners; + float rTop = (roundedCorners & ROUNDED_TOP_CORNERS) == 0 ? 0 : getBackgroundRadius(); + float rBot = (roundedCorners & ROUNDED_BOTTOM_CORNERS) == 0 ? 0 : getBackgroundRadius(); + float[] radii = new float[] {rTop, rTop, rTop, rTop, rBot, rBot, rBot, rBot}; + ShapeDrawable roundRectBackground = new ShapeDrawable(new RoundRectShape(radii, null, null)); + roundRectBackground.getPaint().setColor(color); + setBackground(roundRectBackground); } protected float getBackgroundRadius() { return getResources().getDimensionPixelSize(R.dimen.bg_round_rect_radius); } - - public abstract int getArrowColor(boolean isArrowAttachedToBottom); - - /** - * Extension of {@link PillRevealOutlineProvider} which scales the icon based on the height. - */ - private static class ZoomRevealOutlineProvider extends PillRevealOutlineProvider { - - private final View mTranslateView; - private final View mZoomView; - - private final float mFullHeight; - private final float mTranslateYMultiplier; - - private final boolean mPivotLeft; - private final float mTranslateX; - private final float mArrowCenter; - - public ZoomRevealOutlineProvider(int x, int y, Rect pillRect, PopupItemView translateView, - View zoomView, boolean isContainerAboveIcon, boolean pivotLeft, float arrowCenter) { - super(x, y, pillRect, translateView.getBackgroundRadius()); - mTranslateView = translateView; - mZoomView = zoomView; - mFullHeight = pillRect.height(); - - mTranslateYMultiplier = isContainerAboveIcon ? 0.5f : -0.5f; - - mPivotLeft = pivotLeft; - mTranslateX = pivotLeft ? arrowCenter : pillRect.right - arrowCenter; - mArrowCenter = arrowCenter; - } - - @Override - public void setProgress(float progress) { - super.setProgress(progress); - - if (mZoomView != null) { - mZoomView.setScaleX(progress); - mZoomView.setScaleY(progress); - } - - float height = mOutline.height(); - mTranslateView.setTranslationY(mTranslateYMultiplier * (mFullHeight - height)); - - float offsetX = Math.min(mOutline.width(), mArrowCenter); - float pivotX = mPivotLeft ? (mOutline.left + offsetX) : (mOutline.right - offsetX); - mTranslateView.setTranslationX(mTranslateX - pivotX); - } - } - - /** - * An interpolator that reverses the current open animation progress. - */ - private static class CloseInterpolator extends LogAccelerateInterpolator { - private float mStartProgress; - private float mRemainingProgress; - - /** - * @param openAnimationProgress The progress that the open interpolator ended at. - */ - public CloseInterpolator(float openAnimationProgress) { - super(100, 0); - mStartProgress = 1f - openAnimationProgress; - mRemainingProgress = openAnimationProgress; - } - - @Override - public float getInterpolation(float v) { - return mStartProgress + super.getInterpolation(v) * mRemainingProgress; - } - } } diff --git a/src/com/android/launcher3/shortcuts/ShortcutsItemView.java b/src/com/android/launcher3/shortcuts/ShortcutsItemView.java index 5b3b02eac..340a6f000 100644 --- a/src/com/android/launcher3/shortcuts/ShortcutsItemView.java +++ b/src/com/android/launcher3/shortcuts/ShortcutsItemView.java @@ -16,12 +16,10 @@ package com.android.launcher3.shortcuts; -import android.animation.Animator; -import android.animation.AnimatorSet; import android.content.Context; import android.graphics.Point; -import android.support.v4.content.ContextCompat; import android.util.AttributeSet; +import android.view.LayoutInflater; import android.view.MotionEvent; import android.view.View; import android.widget.LinearLayout; @@ -30,9 +28,7 @@ import com.android.launcher3.AbstractFloatingView; import com.android.launcher3.BubbleTextView; import com.android.launcher3.ItemInfo; import com.android.launcher3.Launcher; -import com.android.launcher3.LauncherAnimUtils; import com.android.launcher3.R; -import com.android.launcher3.anim.PropertyListBuilder; import com.android.launcher3.dragndrop.DragOptions; import com.android.launcher3.dragndrop.DragView; import com.android.launcher3.logging.UserEventDispatcher.LogContainerProvider; @@ -135,7 +131,17 @@ public class ShortcutsItemView extends PopupItemView implements View.OnLongClick if (mSystemShortcutIcons == null) { mSystemShortcutIcons = (LinearLayout) mLauncher.getLayoutInflater().inflate( R.layout.system_shortcut_icons, mShortcutsLayout, false); - mShortcutsLayout.addView(mSystemShortcutIcons, 0); + + View divider = LayoutInflater.from(getContext()).inflate( + R.layout.horizontal_divider, this, false); + + if (mShortcutsLayout.getChildCount() > 0) { + mShortcutsLayout.addView(divider); + } + mShortcutsLayout.addView(mSystemShortcutIcons); + if (mShortcutsLayout.getChildCount() == 1) { + mShortcutsLayout.addView(divider); + } } mSystemShortcutIcons.addView(shortcutView, index); } else { @@ -210,51 +216,6 @@ public class ShortcutsItemView extends PopupItemView implements View.OnLongClick } @Override - public Animator createOpenAnimation(boolean isContainerAboveIcon, boolean pivotLeft) { - AnimatorSet openAnimation = LauncherAnimUtils.createAnimatorSet(); - openAnimation.play(super.createOpenAnimation(isContainerAboveIcon, pivotLeft)); - for (int i = 0; i < mShortcutsLayout.getChildCount(); i++) { - if (!(mShortcutsLayout.getChildAt(i) instanceof DeepShortcutView)) { - continue; - } - DeepShortcutView shortcutView = ((DeepShortcutView) mShortcutsLayout.getChildAt(i)); - View deepShortcutIcon = shortcutView.getIconView(); - deepShortcutIcon.setScaleX(0); - deepShortcutIcon.setScaleY(0); - openAnimation.play(LauncherAnimUtils.ofPropertyValuesHolder( - deepShortcutIcon, new PropertyListBuilder().scale(1).build())); - } - return openAnimation; - } - - @Override - public Animator createCloseAnimation(boolean isContainerAboveIcon, boolean pivotLeft, - long duration) { - AnimatorSet closeAnimation = LauncherAnimUtils.createAnimatorSet(); - closeAnimation.play(super.createCloseAnimation(isContainerAboveIcon, pivotLeft, duration)); - for (int i = 0; i < mShortcutsLayout.getChildCount(); i++) { - if (!(mShortcutsLayout.getChildAt(i) instanceof DeepShortcutView)) { - continue; - } - DeepShortcutView shortcutView = ((DeepShortcutView) mShortcutsLayout.getChildAt(i)); - View deepShortcutIcon = shortcutView.getIconView(); - deepShortcutIcon.setScaleX(1); - deepShortcutIcon.setScaleY(1); - closeAnimation.play(LauncherAnimUtils.ofPropertyValuesHolder( - deepShortcutIcon, new PropertyListBuilder().scale(0).build())); - } - return closeAnimation; - } - - @Override - public int getArrowColor(boolean isArrowAttachedToBottom) { - return ContextCompat.getColor(getContext(), - isArrowAttachedToBottom || mSystemShortcutIcons == null - ? R.color.popup_background_color - : R.color.popup_header_background_color); - } - - @Override public void fillInLogContainerData(View v, ItemInfo info, LauncherLogProto.Target target, LauncherLogProto.Target targetParent) { target.itemType = LauncherLogProto.ItemType.DEEPSHORTCUT; |