Merge "Show more shortcuts when last notification is dimissed" into ub-launcher3-dorval-polish
This commit is contained in:
@@ -22,10 +22,18 @@
|
||||
android:elevation="@dimen/deep_shortcuts_elevation">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/deep_shortcuts"
|
||||
android:id="@+id/content"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical">
|
||||
|
||||
<!-- The shortcuts header is added at runtime when necessary. -->
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/shortcuts"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical" />
|
||||
</LinearLayout>
|
||||
|
||||
</com.android.launcher3.shortcuts.ShortcutsItemView>
|
||||
|
||||
@@ -21,4 +21,7 @@
|
||||
android:layout_height="@dimen/system_shortcut_header_height"
|
||||
android:orientation="horizontal"
|
||||
android:gravity="end|center_vertical"
|
||||
android:background="?attr/popupColorSecondary" />
|
||||
android:background="?attr/popupColorSecondary"
|
||||
android:elevation="1dp"
|
||||
android:outlineProvider="none" />
|
||||
<!-- We have elevation so this is drawn on top, but no outline provider to remove shadow -->
|
||||
|
||||
@@ -86,11 +86,16 @@ public class NotificationItemView extends PopupItemView implements LogContainerP
|
||||
return getHeight() - footerHeight;
|
||||
}
|
||||
|
||||
public Animator animateHeightRemoval(int heightToRemove) {
|
||||
public Animator animateHeightRemoval(int heightToRemove, boolean shouldRemoveFromTop) {
|
||||
Rect startRect = new Rect(mPillRect);
|
||||
Rect endRect = new Rect(mPillRect);
|
||||
endRect.bottom -= heightToRemove;
|
||||
if (shouldRemoveFromTop) {
|
||||
endRect.top += heightToRemove;
|
||||
} else {
|
||||
endRect.bottom -= heightToRemove;
|
||||
}
|
||||
return new RoundedRectRevealOutlineProvider(getBackgroundRadius(), getBackgroundRadius(),
|
||||
mPillRect, endRect, mRoundedCorners).createRevealAnimator(this, false);
|
||||
startRect, endRect, mRoundedCorners).createRevealAnimator(this, false);
|
||||
}
|
||||
|
||||
public void updateHeader(int notificationCount, @Nullable IconPalette palette) {
|
||||
|
||||
@@ -82,6 +82,7 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
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;
|
||||
@@ -191,7 +192,7 @@ public class PopupContainerWithArrow extends AbstractFloatingView implements Dra
|
||||
// Add dummy views first, and populate with real info when ready.
|
||||
PopupPopulator.Item[] itemsToPopulate = PopupPopulator
|
||||
.getItemsToPopulate(shortcutIds, notificationKeys, systemShortcuts);
|
||||
addDummyViews(itemsToPopulate, notificationKeys.size() > 1);
|
||||
addDummyViews(itemsToPopulate, notificationKeys.size());
|
||||
|
||||
measure(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED);
|
||||
orientAboutIcon(originalIcon, arrowHeight + arrowVerticalOffset);
|
||||
@@ -202,7 +203,7 @@ public class PopupContainerWithArrow extends AbstractFloatingView implements Dra
|
||||
mNotificationItemView = null;
|
||||
mShortcutsItemView = null;
|
||||
itemsToPopulate = PopupPopulator.reverseItems(itemsToPopulate);
|
||||
addDummyViews(itemsToPopulate, notificationKeys.size() > 1);
|
||||
addDummyViews(itemsToPopulate, notificationKeys.size());
|
||||
|
||||
measure(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED);
|
||||
orientAboutIcon(originalIcon, arrowHeight + arrowVerticalOffset);
|
||||
@@ -252,8 +253,7 @@ public class PopupContainerWithArrow extends AbstractFloatingView implements Dra
|
||||
systemShortcuts, systemShortcutViews));
|
||||
}
|
||||
|
||||
private void addDummyViews(PopupPopulator.Item[] itemTypesToPopulate,
|
||||
boolean notificationFooterHasIcons) {
|
||||
private void addDummyViews(PopupPopulator.Item[] itemTypesToPopulate, int numNotifications) {
|
||||
final Resources res = getResources();
|
||||
final LayoutInflater inflater = mLauncher.getLayoutInflater();
|
||||
|
||||
@@ -274,6 +274,7 @@ public class PopupContainerWithArrow extends AbstractFloatingView implements Dra
|
||||
|
||||
if (itemTypeToPopulate == PopupPopulator.Item.NOTIFICATION) {
|
||||
mNotificationItemView = (NotificationItemView) item;
|
||||
boolean notificationFooterHasIcons = numNotifications > 1;
|
||||
int footerHeight = notificationFooterHasIcons ?
|
||||
res.getDimensionPixelSize(R.dimen.notification_footer_height) : 0;
|
||||
item.findViewById(R.id.footer).getLayoutParams().height = footerHeight;
|
||||
@@ -316,6 +317,9 @@ public class PopupContainerWithArrow extends AbstractFloatingView implements Dra
|
||||
int backgroundColor = Themes.getAttrColor(mLauncher, mNotificationItemView == null
|
||||
? R.attr.popupColorPrimary : R.attr.popupColorSecondary);
|
||||
mShortcutsItemView.setBackgroundWithCorners(backgroundColor, shortcutsItemRoundedCorners);
|
||||
if (numNotifications > 0) {
|
||||
mShortcutsItemView.hideShortcuts(mIsAboveIcon, MAX_SHORTCUTS_IF_NOTIFICATIONS);
|
||||
}
|
||||
}
|
||||
|
||||
protected PopupItemView getItemViewAt(int index) {
|
||||
@@ -639,11 +643,22 @@ public class PopupContainerWithArrow extends AbstractFloatingView implements Dra
|
||||
ItemInfo originalInfo = (ItemInfo) mOriginalIcon.getTag();
|
||||
BadgeInfo badgeInfo = updatedBadges.get(PackageUserKey.fromItemInfo(originalInfo));
|
||||
if (badgeInfo == null || badgeInfo.getNotificationKeys().size() == 0) {
|
||||
// There are no more notifications, so create an animation to remove
|
||||
// the notifications view and expand the shortcuts view (if possible).
|
||||
AnimatorSet removeNotification = LauncherAnimUtils.createAnimatorSet();
|
||||
int hiddenShortcutsHeight = 0;
|
||||
if (mShortcutsItemView != null) {
|
||||
hiddenShortcutsHeight = mShortcutsItemView.getHiddenShortcutsHeight();
|
||||
int backgroundColor = Themes.getAttrColor(mLauncher, R.attr.popupColorPrimary);
|
||||
// With notifications gone, all corners of shortcuts item should be rounded.
|
||||
mShortcutsItemView.setBackgroundWithCorners(backgroundColor,
|
||||
ROUNDED_TOP_CORNERS | ROUNDED_BOTTOM_CORNERS);
|
||||
removeNotification.play(mShortcutsItemView.showAllShortcuts(mIsAboveIcon));
|
||||
}
|
||||
final int duration = getResources().getInteger(
|
||||
R.integer.config_removeNotificationViewDuration);
|
||||
removeNotification.play(reduceNotificationViewHeight(
|
||||
mNotificationItemView.getHeightMinusFooter(), duration));
|
||||
removeNotification.play(adjustItemHeights(mNotificationItemView.getHeightMinusFooter(),
|
||||
hiddenShortcutsHeight, duration));
|
||||
Animator fade = ObjectAnimator.ofFloat(mNotificationItemView, ALPHA, 0)
|
||||
.setDuration(duration);
|
||||
fade.addListener(new AnimatorListenerAdapter() {
|
||||
@@ -665,12 +680,6 @@ public class PopupContainerWithArrow extends AbstractFloatingView implements Dra
|
||||
showArrow.setStartDelay((long) (duration - arrowScaleDuration * 1.5));
|
||||
removeNotification.playSequentially(hideArrow, showArrow);
|
||||
removeNotification.start();
|
||||
if (mShortcutsItemView != null) {
|
||||
int backgroundColor = Themes.getAttrColor(mLauncher, R.attr.popupColorPrimary);
|
||||
// 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(
|
||||
@@ -689,28 +698,50 @@ public class PopupContainerWithArrow extends AbstractFloatingView implements Dra
|
||||
mArrow, new PropertyListBuilder().scale(scale).build());
|
||||
}
|
||||
|
||||
public Animator reduceNotificationViewHeight(int heightToRemove, int duration) {
|
||||
return adjustItemHeights(heightToRemove, 0, duration);
|
||||
}
|
||||
|
||||
/**
|
||||
* Animates the height of the notification item and the translationY of other items accordingly.
|
||||
*/
|
||||
public Animator reduceNotificationViewHeight(int heightToRemove, int duration) {
|
||||
public Animator adjustItemHeights(int notificationHeightToRemove, int shortcutHeightToAdd,
|
||||
int duration) {
|
||||
if (mReduceHeightAnimatorSet != null) {
|
||||
mReduceHeightAnimatorSet.cancel();
|
||||
}
|
||||
final int translateYBy = mIsAboveIcon ? heightToRemove : -heightToRemove;
|
||||
final int translateYBy = mIsAboveIcon ? notificationHeightToRemove - shortcutHeightToAdd
|
||||
: -notificationHeightToRemove;
|
||||
mReduceHeightAnimatorSet = LauncherAnimUtils.createAnimatorSet();
|
||||
mReduceHeightAnimatorSet.play(mNotificationItemView.animateHeightRemoval(heightToRemove));
|
||||
boolean removingNotification =
|
||||
notificationHeightToRemove == mNotificationItemView.getHeightMinusFooter();
|
||||
boolean shouldRemoveNotificationHeightFromTop = mIsAboveIcon && removingNotification;
|
||||
mReduceHeightAnimatorSet.play(mNotificationItemView.animateHeightRemoval(
|
||||
notificationHeightToRemove, shouldRemoveNotificationHeightFromTop));
|
||||
PropertyResetListener<View, Float> resetTranslationYListener
|
||||
= new PropertyResetListener<>(TRANSLATION_Y, 0f);
|
||||
boolean itemIsAfterShortcuts = false;
|
||||
for (int i = 0; i < getItemCount(); i++) {
|
||||
final PopupItemView itemView = getItemViewAt(i);
|
||||
if (!mIsAboveIcon && itemView == mNotificationItemView) {
|
||||
// The notification view is already in the right place when container is below icon.
|
||||
if (itemIsAfterShortcuts) {
|
||||
// Every item after the shortcuts item needs to adjust for the new height.
|
||||
itemView.setTranslationY(itemView.getTranslationY() - shortcutHeightToAdd);
|
||||
}
|
||||
if (itemView == mNotificationItemView && (!mIsAboveIcon || removingNotification)) {
|
||||
// The notification view is already in the right place.
|
||||
continue;
|
||||
}
|
||||
ValueAnimator translateItem = ObjectAnimator.ofFloat(itemView, TRANSLATION_Y,
|
||||
itemView.getTranslationY() + translateYBy).setDuration(duration);
|
||||
translateItem.addListener(resetTranslationYListener);
|
||||
mReduceHeightAnimatorSet.play(translateItem);
|
||||
if (itemView == mShortcutsItemView) {
|
||||
itemIsAfterShortcuts = true;
|
||||
}
|
||||
}
|
||||
if (mIsAboveIcon) {
|
||||
// We also need to adjust the arrow position to account for the new shortcuts height.
|
||||
mArrow.setTranslationY(mArrow.getTranslationY() - shortcutHeightToAdd);
|
||||
}
|
||||
mReduceHeightAnimatorSet.addListener(new AnimatorListenerAdapter() {
|
||||
@Override
|
||||
@@ -720,6 +751,7 @@ public class PopupContainerWithArrow extends AbstractFloatingView implements Dra
|
||||
// container itself did not. This means the items would jump back to their
|
||||
// original translation unless we update the container's translationY here.
|
||||
setTranslationY(getTranslationY() + translateYBy);
|
||||
mArrow.setTranslationY(0);
|
||||
}
|
||||
mReduceHeightAnimatorSet = null;
|
||||
}
|
||||
|
||||
@@ -52,9 +52,9 @@ import java.util.List;
|
||||
*/
|
||||
public class PopupPopulator {
|
||||
|
||||
public static final int MAX_ITEMS = 4;
|
||||
public static final int MAX_SHORTCUTS = 4;
|
||||
@VisibleForTesting static final int NUM_DYNAMIC = 2;
|
||||
private static final int MAX_SHORTCUTS_IF_NOTIFICATIONS = 2;
|
||||
public static final int MAX_SHORTCUTS_IF_NOTIFICATIONS = 2;
|
||||
|
||||
public enum Item {
|
||||
SHORTCUT(R.layout.deep_shortcut, true),
|
||||
@@ -77,10 +77,7 @@ public class PopupPopulator {
|
||||
boolean hasNotifications = notificationKeys.size() > 0;
|
||||
int numNotificationItems = hasNotifications ? 1 : 0;
|
||||
int numShortcuts = shortcutIds.size();
|
||||
if (hasNotifications && numShortcuts > MAX_SHORTCUTS_IF_NOTIFICATIONS) {
|
||||
numShortcuts = MAX_SHORTCUTS_IF_NOTIFICATIONS;
|
||||
}
|
||||
int numItems = Math.min(MAX_ITEMS, numShortcuts + numNotificationItems)
|
||||
int numItems = Math.min(MAX_SHORTCUTS, numShortcuts) + numNotificationItems
|
||||
+ systemShortcuts.size();
|
||||
Item[] items = new Item[numItems];
|
||||
for (int i = 0; i < numItems; i++) {
|
||||
@@ -126,12 +123,12 @@ public class PopupPopulator {
|
||||
};
|
||||
|
||||
/**
|
||||
* Filters the shortcuts so that only MAX_ITEMS or fewer shortcuts are retained.
|
||||
* Filters the shortcuts so that only MAX_SHORTCUTS or fewer shortcuts are retained.
|
||||
* We want the filter to include both static and dynamic shortcuts, so we always
|
||||
* include NUM_DYNAMIC dynamic shortcuts, if at least that many are present.
|
||||
*
|
||||
* @param shortcutIdToRemoveFirst An id that should be filtered out first, if any.
|
||||
* @return a subset of shortcuts, in sorted order, with size <= MAX_ITEMS.
|
||||
* @return a subset of shortcuts, in sorted order, with size <= MAX_SHORTCUTS.
|
||||
*/
|
||||
public static List<ShortcutInfoCompat> sortAndFilterShortcuts(
|
||||
List<ShortcutInfoCompat> shortcuts, @Nullable String shortcutIdToRemoveFirst) {
|
||||
@@ -147,27 +144,27 @@ public class PopupPopulator {
|
||||
}
|
||||
|
||||
Collections.sort(shortcuts, SHORTCUT_RANK_COMPARATOR);
|
||||
if (shortcuts.size() <= MAX_ITEMS) {
|
||||
if (shortcuts.size() <= MAX_SHORTCUTS) {
|
||||
return shortcuts;
|
||||
}
|
||||
|
||||
// The list of shortcuts is now sorted with static shortcuts followed by dynamic
|
||||
// shortcuts. We want to preserve this order, but only keep MAX_ITEMS.
|
||||
List<ShortcutInfoCompat> filteredShortcuts = new ArrayList<>(MAX_ITEMS);
|
||||
// shortcuts. We want to preserve this order, but only keep MAX_SHORTCUTS.
|
||||
List<ShortcutInfoCompat> filteredShortcuts = new ArrayList<>(MAX_SHORTCUTS);
|
||||
int numDynamic = 0;
|
||||
int size = shortcuts.size();
|
||||
for (int i = 0; i < size; i++) {
|
||||
ShortcutInfoCompat shortcut = shortcuts.get(i);
|
||||
int filteredSize = filteredShortcuts.size();
|
||||
if (filteredSize < MAX_ITEMS) {
|
||||
// Always add the first MAX_ITEMS to the filtered list.
|
||||
if (filteredSize < MAX_SHORTCUTS) {
|
||||
// Always add the first MAX_SHORTCUTS to the filtered list.
|
||||
filteredShortcuts.add(shortcut);
|
||||
if (shortcut.isDynamic()) {
|
||||
numDynamic++;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
// At this point, we have MAX_ITEMS already, but they may all be static.
|
||||
// At this point, we have MAX_SHORTCUTS already, but they may all be static.
|
||||
// If there are dynamic shortcuts, remove static shortcuts to add them.
|
||||
if (shortcut.isDynamic() && numDynamic < NUM_DYNAMIC) {
|
||||
numDynamic++;
|
||||
|
||||
@@ -16,8 +16,12 @@
|
||||
|
||||
package com.android.launcher3.shortcuts;
|
||||
|
||||
import android.animation.Animator;
|
||||
import android.animation.AnimatorSet;
|
||||
import android.animation.ObjectAnimator;
|
||||
import android.content.Context;
|
||||
import android.graphics.Point;
|
||||
import android.graphics.Rect;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.MotionEvent;
|
||||
@@ -28,7 +32,9 @@ 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.RoundedRectRevealOutlineProvider;
|
||||
import com.android.launcher3.dragndrop.DragOptions;
|
||||
import com.android.launcher3.dragndrop.DragView;
|
||||
import com.android.launcher3.logging.UserEventDispatcher.LogContainerProvider;
|
||||
@@ -50,6 +56,7 @@ public class ShortcutsItemView extends PopupItemView implements View.OnLongClick
|
||||
View.OnTouchListener, LogContainerProvider {
|
||||
|
||||
private Launcher mLauncher;
|
||||
private LinearLayout mContent;
|
||||
private LinearLayout mShortcutsLayout;
|
||||
private LinearLayout mSystemShortcutIcons;
|
||||
private final Point mIconShift = new Point();
|
||||
@@ -57,6 +64,8 @@ public class ShortcutsItemView extends PopupItemView implements View.OnLongClick
|
||||
private final List<DeepShortcutView> mDeepShortcutViews = new ArrayList<>();
|
||||
private final List<View> mSystemShortcutViews = new ArrayList<>();
|
||||
|
||||
private int mHiddenShortcutsHeight;
|
||||
|
||||
public ShortcutsItemView(Context context) {
|
||||
this(context, null, 0);
|
||||
}
|
||||
@@ -74,7 +83,8 @@ public class ShortcutsItemView extends PopupItemView implements View.OnLongClick
|
||||
@Override
|
||||
protected void onFinishInflate() {
|
||||
super.onFinishInflate();
|
||||
mShortcutsLayout = findViewById(R.id.deep_shortcuts);
|
||||
mContent = findViewById(R.id.content);
|
||||
mShortcutsLayout = findViewById(R.id.shortcuts);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -130,17 +140,18 @@ public class ShortcutsItemView extends PopupItemView implements View.OnLongClick
|
||||
// System shortcut icons are added to a header that is separate from the full shortcuts.
|
||||
if (mSystemShortcutIcons == null) {
|
||||
mSystemShortcutIcons = (LinearLayout) mLauncher.getLayoutInflater().inflate(
|
||||
R.layout.system_shortcut_icons, mShortcutsLayout, false);
|
||||
R.layout.system_shortcut_icons, mContent, false);
|
||||
|
||||
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);
|
||||
boolean iconsAreBelowShortcuts = mShortcutsLayout.getChildCount() > 0;
|
||||
if (iconsAreBelowShortcuts) {
|
||||
mContent.addView(divider);
|
||||
mContent.addView(mSystemShortcutIcons);
|
||||
} else {
|
||||
mContent.addView(divider, 0);
|
||||
mContent.addView(mSystemShortcutIcons, 0);
|
||||
}
|
||||
}
|
||||
mSystemShortcutIcons.addView(shortcutView, index);
|
||||
@@ -171,6 +182,84 @@ public class ShortcutsItemView extends PopupItemView implements View.OnLongClick
|
||||
return mSystemShortcutViews;
|
||||
}
|
||||
|
||||
/**
|
||||
* Hides shortcuts until only {@param maxShortcuts} are showing.
|
||||
*/
|
||||
public void hideShortcuts(boolean hideFromTop, int maxShortcuts) {
|
||||
int numToHide = mShortcutsLayout.getChildCount() - maxShortcuts;
|
||||
if (numToHide <= 0) {
|
||||
return;
|
||||
}
|
||||
mHiddenShortcutsHeight = 0;
|
||||
final int numShortcuts = mShortcutsLayout.getChildCount();
|
||||
final int dir = hideFromTop ? 1 : -1;
|
||||
for (int i = hideFromTop ? 0 : numShortcuts - 1; 0 <= i && i < numShortcuts; i += dir) {
|
||||
View child = mShortcutsLayout.getChildAt(i);
|
||||
if (child instanceof DeepShortcutView) {
|
||||
mHiddenShortcutsHeight += child.getLayoutParams().height;
|
||||
child.setVisibility(GONE);
|
||||
int prev = i + dir;
|
||||
if (!hideFromTop && 0 <= prev && prev < numShortcuts) {
|
||||
// When hiding views from the bottom, make sure to hide the last divider.
|
||||
mShortcutsLayout.getChildAt(prev).findViewById(R.id.divider).setVisibility(GONE);
|
||||
}
|
||||
numToHide--;
|
||||
if (numToHide == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public int getHiddenShortcutsHeight() {
|
||||
return mHiddenShortcutsHeight;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets all shortcuts in {@link #mShortcutsLayout} to VISIBLE, then creates an
|
||||
* animation to reveal the newly shown shortcuts.
|
||||
*
|
||||
* @see #hideShortcuts(boolean, int)
|
||||
*/
|
||||
public Animator showAllShortcuts(boolean showFromTop) {
|
||||
// First set all the shortcuts to VISIBLE.
|
||||
final int numShortcuts = mShortcutsLayout.getChildCount();
|
||||
for (int i = 0; i < numShortcuts; i++) {
|
||||
DeepShortcutView view = (DeepShortcutView) mShortcutsLayout.getChildAt(i);
|
||||
view.setVisibility(VISIBLE);
|
||||
if (i < numShortcuts - 1) {
|
||||
view.findViewById(R.id.divider).setVisibility(VISIBLE);
|
||||
}
|
||||
}
|
||||
|
||||
// Now reveal the newly shown shortcuts.
|
||||
AnimatorSet animation = LauncherAnimUtils.createAnimatorSet();
|
||||
|
||||
if (showFromTop) {
|
||||
// The new shortcuts pushed the original shortcuts down, but we want to animate them
|
||||
// to that position. So we revert the translation and animate to the new.
|
||||
animation.play(ObjectAnimator.ofFloat(mShortcutsLayout, TRANSLATION_Y,
|
||||
mShortcutsLayout.getTranslationY() - mHiddenShortcutsHeight,
|
||||
mShortcutsLayout.getTranslationY()));
|
||||
} else if (mSystemShortcutIcons != null) {
|
||||
// When adding the shortcuts from the bottom, things are a little trickier, since
|
||||
// that means they push the icons header down. To account for this, we do the same
|
||||
// translation trick as above, but on the header. Since this means leaving behind
|
||||
// a blank area where the header was, we also need to clip the background.
|
||||
animation.play(ObjectAnimator.ofFloat(mSystemShortcutIcons, TRANSLATION_Y,
|
||||
mSystemShortcutIcons.getTranslationY() - mHiddenShortcutsHeight,
|
||||
mSystemShortcutIcons.getTranslationY()));
|
||||
// mPillRect is the bounds of this view before the new shortcuts were shown.
|
||||
Rect backgroundStartRect = new Rect(mPillRect);
|
||||
Rect backgroundEndRect = new Rect(mPillRect);
|
||||
backgroundEndRect.bottom += mHiddenShortcutsHeight;
|
||||
animation.play(new RoundedRectRevealOutlineProvider(getBackgroundRadius(),
|
||||
getBackgroundRadius(), backgroundStartRect, backgroundEndRect, mRoundedCorners)
|
||||
.createRevealAnimator(this, false));
|
||||
}
|
||||
return animation;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a {@link SystemShortcut.Widgets} item if there are widgets for the given ItemInfo.
|
||||
*/
|
||||
|
||||
@@ -28,7 +28,7 @@ import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import static com.android.launcher3.popup.PopupPopulator.MAX_ITEMS;
|
||||
import static com.android.launcher3.popup.PopupPopulator.MAX_SHORTCUTS;
|
||||
import static com.android.launcher3.popup.PopupPopulator.NUM_DYNAMIC;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
@@ -44,18 +44,18 @@ public class PopupPopulatorTest {
|
||||
public void testSortAndFilterShortcuts() {
|
||||
filterShortcutsAndAssertNumStaticAndDynamic(createShortcutsList(3, 0), 3, 0);
|
||||
filterShortcutsAndAssertNumStaticAndDynamic(createShortcutsList(0, 3), 0, 3);
|
||||
filterShortcutsAndAssertNumStaticAndDynamic(createShortcutsList(5, 0), MAX_ITEMS, 0);
|
||||
filterShortcutsAndAssertNumStaticAndDynamic(createShortcutsList(0, 5), 0, MAX_ITEMS);
|
||||
filterShortcutsAndAssertNumStaticAndDynamic(createShortcutsList(5, 0), MAX_SHORTCUTS, 0);
|
||||
filterShortcutsAndAssertNumStaticAndDynamic(createShortcutsList(0, 5), 0, MAX_SHORTCUTS);
|
||||
filterShortcutsAndAssertNumStaticAndDynamic(createShortcutsList(3, 3),
|
||||
MAX_ITEMS - NUM_DYNAMIC, NUM_DYNAMIC);
|
||||
MAX_SHORTCUTS - NUM_DYNAMIC, NUM_DYNAMIC);
|
||||
filterShortcutsAndAssertNumStaticAndDynamic(createShortcutsList(5, 5),
|
||||
MAX_ITEMS - NUM_DYNAMIC, NUM_DYNAMIC);
|
||||
filterShortcutsAndAssertNumStaticAndDynamic(createShortcutsList(5, 1), MAX_ITEMS - 1, 1);
|
||||
filterShortcutsAndAssertNumStaticAndDynamic(createShortcutsList(1, 5), 1, MAX_ITEMS - 1);
|
||||
MAX_SHORTCUTS - NUM_DYNAMIC, NUM_DYNAMIC);
|
||||
filterShortcutsAndAssertNumStaticAndDynamic(createShortcutsList(5, 1), MAX_SHORTCUTS - 1, 1);
|
||||
filterShortcutsAndAssertNumStaticAndDynamic(createShortcutsList(1, 5), 1, MAX_SHORTCUTS - 1);
|
||||
filterShortcutsAndAssertNumStaticAndDynamic(createShortcutsList(5, 3),
|
||||
MAX_ITEMS - NUM_DYNAMIC, NUM_DYNAMIC);
|
||||
MAX_SHORTCUTS - NUM_DYNAMIC, NUM_DYNAMIC);
|
||||
filterShortcutsAndAssertNumStaticAndDynamic(createShortcutsList(3, 5),
|
||||
MAX_ITEMS - NUM_DYNAMIC, NUM_DYNAMIC);
|
||||
MAX_SHORTCUTS - NUM_DYNAMIC, NUM_DYNAMIC);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
Reference in New Issue
Block a user