diff options
author | Sunny Goyal <sunnygoyal@google.com> | 2018-03-30 17:10:13 -0700 |
---|---|---|
committer | Sunny Goyal <sunnygoyal@google.com> | 2018-04-02 12:28:47 -0700 |
commit | 2fd7a8bc596f6ec28098b8566203d3b552ac2d39 (patch) | |
tree | 4192dc993f8a24ffcbebe7ddea590541599aeecc /src/com/android/launcher3/popup/PopupContainerWithArrow.java | |
parent | 415a1402d5894f6b9455267c88bdcbc0f0ab8174 (diff) | |
download | android_packages_apps_Trebuchet-2fd7a8bc596f6ec28098b8566203d3b552ac2d39.tar.gz android_packages_apps_Trebuchet-2fd7a8bc596f6ec28098b8566203d3b552ac2d39.tar.bz2 android_packages_apps_Trebuchet-2fd7a8bc596f6ec28098b8566203d3b552ac2d39.zip |
Updating the UI of the options popup to make it look similar to icon popup
Bug: 77327164
Change-Id: I3580df8bf8a43cb44123f203ffed9a85fa33aea7
Diffstat (limited to 'src/com/android/launcher3/popup/PopupContainerWithArrow.java')
-rw-r--r-- | src/com/android/launcher3/popup/PopupContainerWithArrow.java | 480 |
1 files changed, 51 insertions, 429 deletions
diff --git a/src/com/android/launcher3/popup/PopupContainerWithArrow.java b/src/com/android/launcher3/popup/PopupContainerWithArrow.java index 033fdf888..422a4ecd2 100644 --- a/src/com/android/launcher3/popup/PopupContainerWithArrow.java +++ b/src/com/android/launcher3/popup/PopupContainerWithArrow.java @@ -16,36 +16,28 @@ package com.android.launcher3.popup; -import android.animation.Animator; -import android.animation.AnimatorListenerAdapter; +import static com.android.launcher3.notification.NotificationMainView.NOTIFICATION_ITEM_INFO; +import static com.android.launcher3.popup.PopupPopulator.MAX_SHORTCUTS; +import static com.android.launcher3.popup.PopupPopulator.MAX_SHORTCUTS_IF_NOTIFICATIONS; +import static com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType; +import static com.android.launcher3.userevent.nano.LauncherLogProto.ItemType; +import static com.android.launcher3.userevent.nano.LauncherLogProto.Target; + import android.animation.AnimatorSet; import android.animation.LayoutTransition; -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.util.AttributeSet; -import android.view.Gravity; -import android.view.LayoutInflater; import android.view.MotionEvent; import android.view.View; import android.view.ViewConfiguration; import android.view.ViewGroup; -import android.view.ViewOutlineProvider; -import android.view.accessibility.AccessibilityEvent; -import android.view.animation.AccelerateDecelerateInterpolator; import android.widget.ImageView; import com.android.launcher3.AbstractFloatingView; @@ -56,20 +48,15 @@ import com.android.launcher3.DropTarget.DragObject; import com.android.launcher3.ItemInfo; import com.android.launcher3.ItemInfoWithIcon; import com.android.launcher3.Launcher; -import com.android.launcher3.LauncherAnimUtils; import com.android.launcher3.LauncherModel; 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.RevealOutlineAnimation; -import com.android.launcher3.anim.RoundedRectRevealOutlineProvider; import com.android.launcher3.badge.BadgeInfo; import com.android.launcher3.dragndrop.DragController; import com.android.launcher3.dragndrop.DragLayer; import com.android.launcher3.dragndrop.DragOptions; import com.android.launcher3.dragndrop.DragView; -import com.android.launcher3.graphics.TriangleShape; import com.android.launcher3.logging.LoggerUtils; import com.android.launcher3.notification.NotificationInfo; import com.android.launcher3.notification.NotificationItemView; @@ -79,85 +66,38 @@ import com.android.launcher3.shortcuts.DeepShortcutView; import com.android.launcher3.shortcuts.ShortcutDragPreviewProvider; import com.android.launcher3.touch.ItemLongClickListener; import com.android.launcher3.util.PackageUserKey; -import com.android.launcher3.util.Themes; import java.util.ArrayList; -import java.util.Collections; import java.util.List; import java.util.Map; import java.util.Set; -import static com.android.launcher3.compat.AccessibilityManagerCompat.sendCustomAccessibilityEvent; -import static com.android.launcher3.notification.NotificationMainView.NOTIFICATION_ITEM_INFO; -import static com.android.launcher3.popup.PopupPopulator.MAX_SHORTCUTS; -import static com.android.launcher3.popup.PopupPopulator.MAX_SHORTCUTS_IF_NOTIFICATIONS; -import static com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType; -import static com.android.launcher3.userevent.nano.LauncherLogProto.ItemType; -import static com.android.launcher3.userevent.nano.LauncherLogProto.Target; - /** * A container for shortcuts to deep links and notifications associated with an app. */ @TargetApi(Build.VERSION_CODES.N) -public class PopupContainerWithArrow extends AbstractFloatingView implements DragSource, +public class PopupContainerWithArrow extends ArrowPopup implements DragSource, DragController.DragListener, View.OnLongClickListener, View.OnTouchListener { private final List<DeepShortcutView> mShortcuts = new ArrayList<>(); private final PointF mInterceptTouchDown = new PointF(); - private final Rect mTempRect = new Rect(); private final Point mIconLastTouchPos = new Point(); private final int mStartDragThreshold; - private final LayoutInflater mInflater; - private final float mOutlineRadius; - private final Launcher mLauncher; private final LauncherAccessibilityDelegate mAccessibilityDelegate; - private final boolean mIsRtl; - - private final int mArrayOffset; - private final View mArrow; private BubbleTextView mOriginalIcon; private NotificationItemView mNotificationItemView; - - private ViewGroup mSystemShortcutContainer; - - private boolean mIsLeftAligned; - protected boolean mIsAboveIcon; private int mNumNotifications; - private int mGravity; - protected Animator mOpenCloseAnimator; - protected boolean mDeferContainerRemoval; - private final Rect mStartRect = new Rect(); - private final Rect mEndRect = new Rect(); + private ViewGroup mSystemShortcutContainer; public PopupContainerWithArrow(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); mStartDragThreshold = getResources().getDimensionPixelSize( R.dimen.deep_shortcuts_start_drag_threshold); - mInflater = LayoutInflater.from(context); - mOutlineRadius = getResources().getDimension(R.dimen.bg_round_rect_radius); - mLauncher = Launcher.getLauncher(context); mAccessibilityDelegate = new ShortcutMenuAccessibilityDelegate(mLauncher); - mIsRtl = Utilities.isRtl(getResources()); - - setClipToOutline(true); - setOutlineProvider(new ViewOutlineProvider() { - @Override - public void getOutline(View view, Outline outline) { - outline.setRoundRect(0, 0, view.getWidth(), view.getHeight(), mOutlineRadius); - } - }); - - // Initialize arrow view - final Resources resources = getResources(); - final int arrowWidth = resources.getDimensionPixelSize(R.dimen.popup_arrow_width); - final int arrowHeight = resources.getDimensionPixelSize(R.dimen.popup_arrow_height); - mArrow = new View(context); - mArrow.setLayoutParams(new DragLayer.LayoutParams(arrowWidth, arrowHeight)); - mArrayOffset = resources.getDimensionPixelSize(R.dimen.popup_arrow_vertical_offset); } public PopupContainerWithArrow(Context context, AttributeSet attrs) { @@ -222,21 +162,6 @@ public class PopupContainerWithArrow extends AbstractFloatingView implements Dra return false; } - @Override - protected void handleClose(boolean animate) { - if (animate) { - animateClose(); - } else { - closeComplete(); - } - } - - public <T extends View> T inflateAndAdd(int resId) { - View view = mInflater.inflate(resId, this, false); - addView(view); - return (T) view; - } - /** * Shows the notifications and deep shortcuts associated with {@param icon}. * @return the container if shown or null. @@ -267,13 +192,30 @@ public class PopupContainerWithArrow extends AbstractFloatingView implements Dra return container; } + @Override + protected void onInflationComplete(boolean isReversed) { + if (isReversed && mNotificationItemView != null) { + mNotificationItemView.inverseGutterMargin(); + } + + // Update dividers + int count = getChildCount(); + DeepShortcutView lastView = null; + for (int i = 0; i < count; i++) { + View view = getChildAt(i); + if (view.getVisibility() == VISIBLE && view instanceof DeepShortcutView) { + if (lastView != null) { + lastView.setDividerVisibility(VISIBLE); + } + lastView = (DeepShortcutView) view; + lastView.setDividerVisibility(INVISIBLE); + } + } + } + private void populateAndShow(final BubbleTextView originalIcon, final List<String> shortcutIds, final List<NotificationKeyData> notificationKeys, List<SystemShortcut> systemShortcuts) { mNumNotifications = notificationKeys.size(); - - setVisibility(View.INVISIBLE); - mLauncher.getDragLayer().addView(this); - mOriginalIcon = originalIcon; // Add views @@ -295,17 +237,15 @@ public class PopupContainerWithArrow extends AbstractFloatingView implements Dra } for (int i = shortcutIds.size(); i > 0; i--) { - mShortcuts.add(inflateAndAdd(R.layout.deep_shortcut)); + mShortcuts.add(inflateAndAdd(R.layout.deep_shortcut, this)); } updateHiddenShortcuts(); if (!systemShortcuts.isEmpty()) { - mSystemShortcutContainer = inflateAndAdd(R.layout.system_shortcut_icons); + mSystemShortcutContainer = inflateAndAdd(R.layout.system_shortcut_icons, this); for (SystemShortcut shortcut : systemShortcuts) { - View view = mInflater.inflate(R.layout.system_shortcut_icon_only, - mSystemShortcutContainer, false); - mSystemShortcutContainer.addView(view); - initializeSystemShortcut(view, shortcut); + initializeSystemShortcut( + R.layout.system_shortcut_icon_only, mSystemShortcutContainer, shortcut); } } } else if (!systemShortcuts.isEmpty()) { @@ -314,68 +254,11 @@ public class PopupContainerWithArrow extends AbstractFloatingView implements Dra } for (SystemShortcut shortcut : systemShortcuts) { - initializeSystemShortcut(inflateAndAdd(R.layout.system_shortcut), shortcut); + initializeSystemShortcut(R.layout.system_shortcut, this, shortcut); } } - orientAboutIcon(); - - boolean reverseOrder = mIsAboveIcon; - if (reverseOrder) { - int count = getChildCount(); - ArrayList<View> allViews = new ArrayList<>(count); - for (int i = 0; i < count; i++) { - if (i == viewsToFlip) { - Collections.reverse(allViews); - } - allViews.add(getChildAt(i)); - } - Collections.reverse(allViews); - removeAllViews(); - for (int i = 0; i < count; i++) { - addView(allViews.get(i)); - } - if (mNotificationItemView != null) { - mNotificationItemView.inverseGutterMargin(); - } - - orientAboutIcon(); - } - updateDividers(); - - // Add the arrow. - final Resources res = getResources(); - final int arrowCenterOffset = res.getDimensionPixelSize(isAlignedWithStart() - ? R.dimen.popup_arrow_horizontal_center_start - : R.dimen.popup_arrow_horizontal_center_end); - final int halfArrowWidth = res.getDimensionPixelSize(R.dimen.popup_arrow_width) / 2; - mLauncher.getDragLayer().addView(mArrow); - DragLayer.LayoutParams arrowLp = (DragLayer.LayoutParams) mArrow.getLayoutParams(); - if (mIsLeftAligned) { - mArrow.setX(getX() + arrowCenterOffset - halfArrowWidth); - } else { - mArrow.setX(getX() + getMeasuredWidth() - arrowCenterOffset - halfArrowWidth); - } - - if (Gravity.isVertical(mGravity)) { - // This is only true if there wasn't room for the container next to the icon, - // so we centered it instead. In that case we don't want to show the arrow. - mArrow.setVisibility(INVISIBLE); - } else { - ShapeDrawable arrowDrawable = new ShapeDrawable(TriangleShape.create( - arrowLp.width, arrowLp.height, !mIsAboveIcon)); - Paint arrowPaint = arrowDrawable.getPaint(); - arrowPaint.setColor(Themes.getAttrColor(mLauncher, R.attr.popupColorPrimary)); - // 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)); - mArrow.setBackground(arrowDrawable); - mArrow.setElevation(getElevation()); - } - - mArrow.setPivotX(arrowLp.width / 2); - mArrow.setPivotY(mIsAboveIcon ? 0 : arrowLp.height); - animateOpen(); + reorderAndShow(viewsToFlip); ItemInfo originalItemInfo = (ItemInfo) originalIcon.getTag(); int numShortcuts = mShortcuts.size() + systemShortcuts.size(); @@ -401,189 +284,15 @@ public class PopupContainerWithArrow extends AbstractFloatingView implements Dra this, shortcutIds, mShortcuts, notificationKeys)); } - protected boolean isAlignedWithStart() { - return mIsLeftAligned && !mIsRtl || !mIsLeftAligned && mIsRtl; - } - - /** - * Orients this container above or below the given icon, aligning with the left or right. - * - * These are the preferred orientations, in order (RTL prefers right-aligned over left): - * - Above and left-aligned - * - Above and right-aligned - * - Below and left-aligned - * - Below and right-aligned - * - * So we always align left if there is enough horizontal space - * and align above if there is enough vertical space. - */ - protected void orientAboutIcon() { - measure(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED); - int width = getMeasuredWidth(); - int extraVerticalSpace = mArrow.getLayoutParams().height + mArrayOffset - + getResources().getDimensionPixelSize(R.dimen.popup_vertical_padding); - int height = getMeasuredHeight() + extraVerticalSpace; - - DragLayer dragLayer = mLauncher.getDragLayer(); - dragLayer.getDescendantRectRelativeToSelf(mOriginalIcon, mTempRect); - Rect insets = dragLayer.getInsets(); - - // Align left (right in RTL) if there is room. - int leftAlignedX = mTempRect.left + mOriginalIcon.getPaddingLeft(); - int rightAlignedX = mTempRect.right - width - mOriginalIcon.getPaddingRight(); - int x = leftAlignedX; - boolean canBeLeftAligned = leftAlignedX + width + insets.left - < dragLayer.getRight() - insets.right; - boolean canBeRightAligned = rightAlignedX > dragLayer.getLeft() + insets.left; - if (!canBeLeftAligned || (mIsRtl && canBeRightAligned)) { - x = rightAlignedX; - } - mIsLeftAligned = x == leftAlignedX; - - // Offset x so that the arrow and shortcut icons are center-aligned with the original icon. - int iconWidth = mOriginalIcon.getWidth() - - mOriginalIcon.getTotalPaddingLeft() - mOriginalIcon.getTotalPaddingRight(); - iconWidth *= mOriginalIcon.getScaleX(); - Resources resources = getResources(); - int xOffset; - if (isAlignedWithStart()) { - // Aligning with the shortcut icon. - int shortcutIconWidth = resources.getDimensionPixelSize(R.dimen.deep_shortcut_icon_size); - int shortcutPaddingStart = resources.getDimensionPixelSize( - R.dimen.popup_padding_start); - xOffset = iconWidth / 2 - shortcutIconWidth / 2 - shortcutPaddingStart; - } else { - // Aligning with the drag handle. - int shortcutDragHandleWidth = resources.getDimensionPixelSize( - R.dimen.deep_shortcut_drag_handle_size); - int shortcutPaddingEnd = resources.getDimensionPixelSize( - R.dimen.popup_padding_end); - xOffset = iconWidth / 2 - shortcutDragHandleWidth / 2 - shortcutPaddingEnd; - } - x += mIsLeftAligned ? xOffset : -xOffset; - - // Open above icon if there is room. - int iconHeight = getIconHeightForPopupPlacement(); - int y = mTempRect.top + mOriginalIcon.getPaddingTop() - height; - mIsAboveIcon = y > dragLayer.getTop() + insets.top; - if (!mIsAboveIcon) { - y = mTempRect.top + mOriginalIcon.getPaddingTop() + iconHeight + extraVerticalSpace; - } - - // Insets are added later, so subtract them now. - if (mIsRtl) { - x += insets.right; - } else { - x -= insets.left; - } - y -= insets.top; - - mGravity = 0; - if (y + height > dragLayer.getBottom() - insets.bottom) { - // The container is opening off the screen, so just center it in the drag layer instead. - mGravity = Gravity.CENTER_VERTICAL; - // Put the container next to the icon, preferring the right side in ltr (left in rtl). - int rightSide = leftAlignedX + iconWidth - insets.left; - int leftSide = rightAlignedX - iconWidth - insets.left; - if (!mIsRtl) { - if (rightSide + width < dragLayer.getRight()) { - x = rightSide; - mIsLeftAligned = true; - } else { - x = leftSide; - mIsLeftAligned = false; - } - } else { - if (leftSide > dragLayer.getLeft()) { - x = leftSide; - mIsLeftAligned = false; - } else { - x = rightSide; - mIsLeftAligned = true; - } - } - mIsAboveIcon = true; - } - - setX(x); - if (Gravity.isVertical(mGravity)) { - return; - } - - DragLayer.LayoutParams lp = (DragLayer.LayoutParams) getLayoutParams(); - DragLayer.LayoutParams arrowLp = (DragLayer.LayoutParams) mArrow.getLayoutParams(); - if (mIsAboveIcon) { - arrowLp.gravity = lp.gravity = Gravity.BOTTOM; - lp.bottomMargin = - mLauncher.getDragLayer().getHeight() - y - getMeasuredHeight() - insets.top; - arrowLp.bottomMargin = lp.bottomMargin - arrowLp.height - mArrayOffset - insets.bottom; - } else { - arrowLp.gravity = lp.gravity = Gravity.TOP; - lp.topMargin = y + insets.top; - arrowLp.topMargin = lp.topMargin - insets.top - arrowLp.height - mArrayOffset; - } - } - @Override - protected void onLayout(boolean changed, int l, int t, int r, int b) { - super.onLayout(changed, l, t, r, b); - - // enforce contained is within screen - DragLayer dragLayer = mLauncher.getDragLayer(); - if (getTranslationX() + l < 0 || getTranslationX() + r > dragLayer.getWidth()) { - // If we are still off screen, center horizontally too. - mGravity |= Gravity.CENTER_HORIZONTAL; - } - - if (Gravity.isHorizontal(mGravity)) { - setX(dragLayer.getWidth() / 2 - getMeasuredWidth() / 2); - mArrow.setVisibility(INVISIBLE); - } - if (Gravity.isVertical(mGravity)) { - setY(dragLayer.getHeight() / 2 - getMeasuredHeight() / 2); - } - } - - protected void animateOpen() { - setVisibility(View.VISIBLE); - mIsOpen = true; - - final AnimatorSet openAnim = LauncherAnimUtils.createAnimatorSet(); - final Resources res = getResources(); - final long revealDuration = (long) res.getInteger(R.integer.config_popupOpenCloseDuration); - final TimeInterpolator revealInterpolator = new AccelerateDecelerateInterpolator(); - - // Rectangular reveal. - final ValueAnimator revealAnim = createOpenCloseOutlineProvider() - .createRevealAnimator(this, false); - revealAnim.setDuration(revealDuration); - revealAnim.setInterpolator(revealInterpolator); - - Animator fadeIn = ObjectAnimator.ofFloat(this, ALPHA, 0, 1); - fadeIn.setDuration(revealDuration); - fadeIn.setInterpolator(revealInterpolator); - openAnim.play(fadeIn); - - // Animate the arrow. - mArrow.setScaleX(0); - mArrow.setScaleY(0); - Animator arrowScale = ObjectAnimator.ofFloat(mArrow, LauncherAnimUtils.SCALE_PROPERTY, 1) - .setDuration(res.getInteger(R.integer.config_popupArrowOpenDuration)); - - openAnim.addListener(new AnimatorListenerAdapter() { - @Override - public void onAnimationEnd(Animator animation) { - mOpenCloseAnimator = null; - sendCustomAccessibilityEvent( - PopupContainerWithArrow.this, - AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED, - getContext().getString(R.string.action_deep_shortcut)); - } - }); - - mOpenCloseAnimator = openAnim; - openAnim.playSequentially(revealAnim, arrowScale); - openAnim.start(); + protected void getTargetObjectLocation(Rect outPos) { + mLauncher.getDragLayer().getDescendantRectRelativeToSelf(mOriginalIcon, outPos); + outPos.top += mOriginalIcon.getPaddingTop(); + outPos.left += mOriginalIcon.getPaddingLeft(); + outPos.right -= mOriginalIcon.getPaddingRight(); + outPos.bottom = outPos.top + (mOriginalIcon.getIcon() != null + ? mOriginalIcon.getIcon().getBounds().height() + : mOriginalIcon.getHeight()); } public void applyNotificationInfos(List<NotificationInfo> notificationInfos) { @@ -642,10 +351,8 @@ public class PopupContainerWithArrow extends AbstractFloatingView implements Dra if (onClickListener != null && widgetsView == null) { // We didn't have any widgets cached but now there are some, so enable the shortcut. if (mSystemShortcutContainer != this) { - View view = mInflater.inflate(R.layout.system_shortcut_icon_only, - mSystemShortcutContainer, false); - mSystemShortcutContainer.addView(view); - initializeSystemShortcut(view, widgetInfo); + initializeSystemShortcut( + R.layout.system_shortcut_icon_only, mSystemShortcutContainer, widgetInfo); } else { // If using the expanded system shortcut (as opposed to just the icon), we need to // reopen the container to ensure measurements etc. all work out. While this could @@ -665,7 +372,8 @@ public class PopupContainerWithArrow extends AbstractFloatingView implements Dra } } - private void initializeSystemShortcut(View view, SystemShortcut info) { + private void initializeSystemShortcut(int resId, ViewGroup container, SystemShortcut info) { + View view = inflateAndAdd(resId, container); if (view instanceof DeepShortcutView) { // Expanded system shortcut, with both icon and text shown on white background. final DeepShortcutView shortcutView = (DeepShortcutView) view; @@ -682,12 +390,6 @@ public class PopupContainerWithArrow extends AbstractFloatingView implements Dra (ItemInfo) mOriginalIcon.getTag())); } - protected int getIconHeightForPopupPlacement() { - return mOriginalIcon.getIcon() != null - ? mOriginalIcon.getIcon().getBounds().height() - : mOriginalIcon.getHeight(); - } - /** * Determines when the deferred drag should be started. * @@ -807,91 +509,11 @@ public class PopupContainerWithArrow extends AbstractFloatingView implements Dra targetParent.containerType = ContainerType.DEEPSHORTCUTS; } - protected void animateClose() { - if (!mIsOpen) { - return; - } - mEndRect.setEmpty(); - if (getOutlineProvider() instanceof RevealOutlineAnimation) { - ((RevealOutlineAnimation) getOutlineProvider()).getOutline(mEndRect); - } - if (mOpenCloseAnimator != null) { - mOpenCloseAnimator.cancel(); - } - mIsOpen = false; - - final AnimatorSet closeAnim = LauncherAnimUtils.createAnimatorSet(); - // Hide the arrow - closeAnim.play(ObjectAnimator.ofFloat(mArrow, LauncherAnimUtils.SCALE_PROPERTY, 0)); - closeAnim.play(ObjectAnimator.ofFloat(mArrow, ALPHA, 0)); - + @Override + protected void onCreateCloseAnimation(AnimatorSet anim) { // Animate original icon's text back in. - closeAnim.play(mOriginalIcon.createTextAlphaAnimator(true /* fadeIn */)); + anim.play(mOriginalIcon.createTextAlphaAnimator(true /* fadeIn */)); mOriginalIcon.forceHideBadge(false); - - final Resources res = getResources(); - final TimeInterpolator revealInterpolator = new AccelerateDecelerateInterpolator(); - - // Rectangular reveal (reversed). - final ValueAnimator revealAnim = createOpenCloseOutlineProvider() - .createRevealAnimator(this, true); - revealAnim.setInterpolator(revealInterpolator); - closeAnim.play(revealAnim); - - Animator fadeOut = ObjectAnimator.ofFloat(this, ALPHA, 0); - fadeOut.setInterpolator(revealInterpolator); - closeAnim.play(fadeOut); - closeAnim.setDuration((long) res.getInteger(R.integer.config_popupOpenCloseDuration)); - - closeAnim.addListener(new AnimatorListenerAdapter() { - @Override - public void onAnimationEnd(Animator animation) { - mOpenCloseAnimator = null; - if (mDeferContainerRemoval) { - setVisibility(INVISIBLE); - } else { - closeComplete(); - } - } - }); - mOpenCloseAnimator = closeAnim; - closeAnim.start(); - } - - private RoundedRectRevealOutlineProvider createOpenCloseOutlineProvider() { - 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 arrowCenterY = mIsAboveIcon ? getMeasuredHeight() : 0; - - mStartRect.set(arrowCenterX, arrowCenterY, arrowCenterX, arrowCenterY); - if (mEndRect.isEmpty()) { - mEndRect.set(0, 0, getMeasuredWidth(), getMeasuredHeight()); - } - - return new RoundedRectRevealOutlineProvider - (mOutlineRadius, mOutlineRadius, mStartRect, mEndRect); - } - - /** - * Closes the popup without animation. - */ - private void closeComplete() { - mOriginalIcon.setTextVisibility(mOriginalIcon.shouldTextBeVisible()); - mOriginalIcon.forceHideBadge(false); - - mLauncher.getDragController().removeDragListener(this); - if (mOpenCloseAnimator != null) { - mOpenCloseAnimator.cancel(); - mOpenCloseAnimator = null; - } - mIsOpen = false; - mDeferContainerRemoval = false; - mLauncher.getDragLayer().removeView(this); - mLauncher.getDragLayer().removeView(mArrow); } @Override |