Remove gap between popup items
am: acaf5b3a37
Change-Id: Ib1644ec746562a61c2533c61c8b220c558f61e06
This commit is contained in:
commit
5101a68b27
|
@ -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>
|
|
|
@ -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"/>
|
|
@ -19,9 +19,7 @@
|
||||||
android:id="@+id/notification_view"
|
android:id="@+id/notification_view"
|
||||||
android:layout_width="@dimen/bg_popup_item_width"
|
android:layout_width="@dimen/bg_popup_item_width"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:elevation="@dimen/deep_shortcuts_elevation"
|
android:elevation="@dimen/deep_shortcuts_elevation">
|
||||||
android:background="@drawable/bg_white_round_rect"
|
|
||||||
android:backgroundTint="@color/notification_color_beneath">
|
|
||||||
|
|
||||||
<RelativeLayout
|
<RelativeLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
|
@ -35,7 +33,7 @@
|
||||||
android:layout_height="@dimen/notification_header_height"
|
android:layout_height="@dimen/notification_header_height"
|
||||||
android:paddingStart="@dimen/notification_padding_start"
|
android:paddingStart="@dimen/notification_padding_start"
|
||||||
android:paddingEnd="@dimen/notification_padding_end"
|
android:paddingEnd="@dimen/notification_padding_end"
|
||||||
android:background="@color/popup_header_background_color"
|
android:background="@color/popup_background_color"
|
||||||
android:elevation="@dimen/notification_elevation">
|
android:elevation="@dimen/notification_elevation">
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/notification_text"
|
android:id="@+id/notification_text"
|
||||||
|
|
|
@ -19,8 +19,7 @@
|
||||||
android:id="@+id/shortcuts_view"
|
android:id="@+id/shortcuts_view"
|
||||||
android:layout_width="@dimen/bg_popup_item_width"
|
android:layout_width="@dimen/bg_popup_item_width"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:elevation="@dimen/deep_shortcuts_elevation"
|
android:elevation="@dimen/deep_shortcuts_elevation">
|
||||||
android:background="@drawable/bg_white_round_rect">
|
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:id="@+id/deep_shortcuts"
|
android:id="@+id/deep_shortcuts"
|
||||||
|
|
|
@ -31,7 +31,7 @@
|
||||||
<color name="spring_loaded_highlighted_panel_border_color">#FFF</color>
|
<color name="spring_loaded_highlighted_panel_border_color">#FFF</color>
|
||||||
|
|
||||||
<!-- Popup container -->
|
<!-- 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="popup_background_color">#FFF</color>
|
||||||
<color name="notification_icon_default_color">#757575</color> <!-- Gray 600 -->
|
<color name="notification_icon_default_color">#757575</color> <!-- Gray 600 -->
|
||||||
<color name="notification_color_beneath">#E0E0E0</color> <!-- Gray 300 -->
|
<color name="notification_color_beneath">#E0E0E0</color> <!-- Gray 300 -->
|
||||||
|
|
|
@ -124,11 +124,8 @@
|
||||||
<item type="id" name="preview_image_id" />
|
<item type="id" name="preview_image_id" />
|
||||||
|
|
||||||
<!-- Popup items -->
|
<!-- Popup items -->
|
||||||
<integer name="config_deepShortcutOpenDuration">220</integer>
|
<integer name="config_popupOpenCloseDuration">220</integer>
|
||||||
<integer name="config_deepShortcutArrowOpenDuration">80</integer>
|
<integer name="config_popupArrowOpenDuration">80</integer>
|
||||||
<integer name="config_deepShortcutOpenStagger">40</integer>
|
|
||||||
<integer name="config_deepShortcutCloseDuration">150</integer>
|
|
||||||
<integer name="config_deepShortcutCloseStagger">20</integer>
|
|
||||||
<integer name="config_removeNotificationViewDuration">300</integer>
|
<integer name="config_removeNotificationViewDuration">300</integer>
|
||||||
|
|
||||||
<!-- Accessibility actions -->
|
<!-- Accessibility actions -->
|
||||||
|
|
|
@ -148,7 +148,6 @@
|
||||||
<dimen name="deep_shortcuts_elevation">9dp</dimen>
|
<dimen name="deep_shortcuts_elevation">9dp</dimen>
|
||||||
<dimen name="bg_popup_item_width">220dp</dimen>
|
<dimen name="bg_popup_item_width">220dp</dimen>
|
||||||
<dimen name="bg_popup_item_height">56dp</dimen>
|
<dimen name="bg_popup_item_height">56dp</dimen>
|
||||||
<dimen name="popup_items_spacing">4dp</dimen>
|
|
||||||
<dimen name="pre_drag_view_scale">6dp</dimen>
|
<dimen name="pre_drag_view_scale">6dp</dimen>
|
||||||
<!-- an icon with shortcuts must be dragged this far before the container is removed. -->
|
<!-- an icon with shortcuts must be dragged this far before the container is removed. -->
|
||||||
<dimen name="deep_shortcuts_start_drag_threshold">16dp</dimen>
|
<dimen name="deep_shortcuts_start_drag_threshold">16dp</dimen>
|
||||||
|
|
|
@ -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));
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -18,6 +18,11 @@ package com.android.launcher3.anim;
|
||||||
|
|
||||||
import android.graphics.Rect;
|
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
|
* A {@link RevealOutlineAnimation} that provides an outline that interpolates between two radii
|
||||||
* and two {@link Rect}s.
|
* and two {@link Rect}s.
|
||||||
|
@ -32,12 +37,21 @@ public class RoundedRectRevealOutlineProvider extends RevealOutlineAnimation {
|
||||||
private final Rect mStartRect;
|
private final Rect mStartRect;
|
||||||
private final Rect mEndRect;
|
private final Rect mEndRect;
|
||||||
|
|
||||||
|
private final @PopupContainerWithArrow.RoundedCornerFlags int mRoundedCorners;
|
||||||
|
|
||||||
public RoundedRectRevealOutlineProvider(float startRadius, float endRadius, Rect startRect,
|
public RoundedRectRevealOutlineProvider(float startRadius, float endRadius, Rect startRect,
|
||||||
Rect endRect) {
|
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;
|
mStartRadius = startRadius;
|
||||||
mEndRadius = endRadius;
|
mEndRadius = endRadius;
|
||||||
mStartRect = startRect;
|
mStartRect = startRect;
|
||||||
mEndRect = endRect;
|
mEndRect = endRect;
|
||||||
|
mRoundedCorners = roundedCorners;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -51,7 +65,13 @@ public class RoundedRectRevealOutlineProvider extends RevealOutlineAnimation {
|
||||||
|
|
||||||
mOutline.left = (int) ((1 - progress) * mStartRect.left + progress * mEndRect.left);
|
mOutline.left = (int) ((1 - progress) * mStartRect.left + progress * mEndRect.left);
|
||||||
mOutline.top = (int) ((1 - progress) * mStartRect.top + progress * mEndRect.top);
|
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.right = (int) ((1 - progress) * mStartRect.right + progress * mEndRect.right);
|
||||||
mOutline.bottom = (int) ((1 - progress) * mStartRect.bottom + progress * mEndRect.bottom);
|
mOutline.bottom = (int) ((1 - progress) * mStartRect.bottom + progress * mEndRect.bottom);
|
||||||
|
if ((mRoundedCorners & ROUNDED_BOTTOM_CORNERS) == 0) {
|
||||||
|
mOutline.bottom += mOutlineRadius;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,7 +21,6 @@ import android.app.Notification;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.graphics.Rect;
|
import android.graphics.Rect;
|
||||||
import android.support.annotation.Nullable;
|
import android.support.annotation.Nullable;
|
||||||
import android.support.v4.content.ContextCompat;
|
|
||||||
import android.util.AttributeSet;
|
import android.util.AttributeSet;
|
||||||
import android.view.MotionEvent;
|
import android.view.MotionEvent;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
|
@ -30,7 +29,7 @@ import android.widget.TextView;
|
||||||
|
|
||||||
import com.android.launcher3.ItemInfo;
|
import com.android.launcher3.ItemInfo;
|
||||||
import com.android.launcher3.R;
|
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.graphics.IconPalette;
|
||||||
import com.android.launcher3.logging.UserEventDispatcher.LogContainerProvider;
|
import com.android.launcher3.logging.UserEventDispatcher.LogContainerProvider;
|
||||||
import com.android.launcher3.popup.PopupItemView;
|
import com.android.launcher3.popup.PopupItemView;
|
||||||
|
@ -87,9 +86,10 @@ public class NotificationItemView extends PopupItemView implements LogContainerP
|
||||||
}
|
}
|
||||||
|
|
||||||
public Animator animateHeightRemoval(int heightToRemove) {
|
public Animator animateHeightRemoval(int heightToRemove) {
|
||||||
final int newHeight = getHeight() - heightToRemove;
|
Rect endRect = new Rect(mPillRect);
|
||||||
return new PillHeightRevealOutlineProvider(mPillRect,
|
endRect.bottom -= heightToRemove;
|
||||||
getBackgroundRadius(), newHeight).createRevealAnimator(this, true /* isReversed */);
|
return new RoundedRectRevealOutlineProvider(getBackgroundRadius(), getBackgroundRadius(),
|
||||||
|
mPillRect, endRect, mRoundedCorners).createRevealAnimator(this, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void updateHeader(int notificationCount, @Nullable IconPalette palette) {
|
public void updateHeader(int notificationCount, @Nullable IconPalette palette) {
|
||||||
|
@ -162,13 +162,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
|
@Override
|
||||||
public void fillInLogContainerData(View v, ItemInfo info, LauncherLogProto.Target target,
|
public void fillInLogContainerData(View v, ItemInfo info, LauncherLogProto.Target target,
|
||||||
LauncherLogProto.Target targetParent) {
|
LauncherLogProto.Target targetParent) {
|
||||||
|
|
|
@ -20,19 +20,22 @@ import android.animation.Animator;
|
||||||
import android.animation.AnimatorListenerAdapter;
|
import android.animation.AnimatorListenerAdapter;
|
||||||
import android.animation.AnimatorSet;
|
import android.animation.AnimatorSet;
|
||||||
import android.animation.ObjectAnimator;
|
import android.animation.ObjectAnimator;
|
||||||
import android.animation.TimeInterpolator;
|
|
||||||
import android.animation.ValueAnimator;
|
import android.animation.ValueAnimator;
|
||||||
import android.annotation.TargetApi;
|
import android.annotation.TargetApi;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.res.Resources;
|
import android.content.res.Resources;
|
||||||
import android.graphics.CornerPathEffect;
|
import android.graphics.CornerPathEffect;
|
||||||
|
import android.graphics.Outline;
|
||||||
import android.graphics.Paint;
|
import android.graphics.Paint;
|
||||||
|
import android.graphics.Point;
|
||||||
import android.graphics.PointF;
|
import android.graphics.PointF;
|
||||||
import android.graphics.Rect;
|
import android.graphics.Rect;
|
||||||
import android.graphics.drawable.ShapeDrawable;
|
import android.graphics.drawable.ShapeDrawable;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.os.Looper;
|
import android.os.Looper;
|
||||||
|
import android.support.annotation.IntDef;
|
||||||
|
import android.support.v4.content.ContextCompat;
|
||||||
import android.util.AttributeSet;
|
import android.util.AttributeSet;
|
||||||
import android.view.Gravity;
|
import android.view.Gravity;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
|
@ -40,7 +43,7 @@ import android.view.MotionEvent;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewConfiguration;
|
import android.view.ViewConfiguration;
|
||||||
import android.view.accessibility.AccessibilityEvent;
|
import android.view.accessibility.AccessibilityEvent;
|
||||||
import android.view.animation.DecelerateInterpolator;
|
import android.view.animation.AccelerateDecelerateInterpolator;
|
||||||
import android.widget.FrameLayout;
|
import android.widget.FrameLayout;
|
||||||
|
|
||||||
import com.android.launcher3.AbstractFloatingView;
|
import com.android.launcher3.AbstractFloatingView;
|
||||||
|
@ -53,13 +56,13 @@ import com.android.launcher3.Launcher;
|
||||||
import com.android.launcher3.LauncherAnimUtils;
|
import com.android.launcher3.LauncherAnimUtils;
|
||||||
import com.android.launcher3.LauncherModel;
|
import com.android.launcher3.LauncherModel;
|
||||||
import com.android.launcher3.LauncherSettings;
|
import com.android.launcher3.LauncherSettings;
|
||||||
import com.android.launcher3.LogAccelerateInterpolator;
|
|
||||||
import com.android.launcher3.R;
|
import com.android.launcher3.R;
|
||||||
import com.android.launcher3.Utilities;
|
import com.android.launcher3.Utilities;
|
||||||
import com.android.launcher3.accessibility.LauncherAccessibilityDelegate;
|
import com.android.launcher3.accessibility.LauncherAccessibilityDelegate;
|
||||||
import com.android.launcher3.accessibility.ShortcutMenuAccessibilityDelegate;
|
import com.android.launcher3.accessibility.ShortcutMenuAccessibilityDelegate;
|
||||||
import com.android.launcher3.anim.PropertyListBuilder;
|
import com.android.launcher3.anim.PropertyListBuilder;
|
||||||
import com.android.launcher3.anim.PropertyResetListener;
|
import com.android.launcher3.anim.PropertyResetListener;
|
||||||
|
import com.android.launcher3.anim.RoundedRectRevealOutlineProvider;
|
||||||
import com.android.launcher3.badge.BadgeInfo;
|
import com.android.launcher3.badge.BadgeInfo;
|
||||||
import com.android.launcher3.dragndrop.DragController;
|
import com.android.launcher3.dragndrop.DragController;
|
||||||
import com.android.launcher3.dragndrop.DragLayer;
|
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.shortcuts.ShortcutsItemView;
|
||||||
import com.android.launcher3.util.PackageUserKey;
|
import com.android.launcher3.util.PackageUserKey;
|
||||||
|
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.RetentionPolicy;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
@ -89,6 +94,16 @@ import static com.android.launcher3.userevent.nano.LauncherLogProto.Target;
|
||||||
public class PopupContainerWithArrow extends AbstractFloatingView implements DragSource,
|
public class PopupContainerWithArrow extends AbstractFloatingView implements DragSource,
|
||||||
DragController.DragListener {
|
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;
|
protected final Launcher mLauncher;
|
||||||
private final int mStartDragThreshold;
|
private final int mStartDragThreshold;
|
||||||
private LauncherAccessibilityDelegate mAccessibilityDelegate;
|
private LauncherAccessibilityDelegate mAccessibilityDelegate;
|
||||||
|
@ -107,6 +122,8 @@ public class PopupContainerWithArrow extends AbstractFloatingView implements Dra
|
||||||
protected Animator mOpenCloseAnimator;
|
protected Animator mOpenCloseAnimator;
|
||||||
private boolean mDeferContainerRemoval;
|
private boolean mDeferContainerRemoval;
|
||||||
private AnimatorSet mReduceHeightAnimatorSet;
|
private AnimatorSet mReduceHeightAnimatorSet;
|
||||||
|
private final Rect mStartRect = new Rect();
|
||||||
|
private final Rect mEndRect = new Rect();
|
||||||
|
|
||||||
public PopupContainerWithArrow(Context context, AttributeSet attrs, int defStyleAttr) {
|
public PopupContainerWithArrow(Context context, AttributeSet attrs, int defStyleAttr) {
|
||||||
super(context, attrs, defStyleAttr);
|
super(context, attrs, defStyleAttr);
|
||||||
|
@ -222,6 +239,7 @@ public class PopupContainerWithArrow extends AbstractFloatingView implements Dra
|
||||||
mArrow.setPivotX(arrowWidth / 2);
|
mArrow.setPivotX(arrowWidth / 2);
|
||||||
mArrow.setPivotY(mIsAboveIcon ? 0 : arrowHeight);
|
mArrow.setPivotY(mIsAboveIcon ? 0 : arrowHeight);
|
||||||
|
|
||||||
|
measure(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED);
|
||||||
animateOpen();
|
animateOpen();
|
||||||
|
|
||||||
mLauncher.getDragController().addDragListener(this);
|
mLauncher.getDragController().addDragListener(this);
|
||||||
|
@ -238,46 +256,66 @@ public class PopupContainerWithArrow extends AbstractFloatingView implements Dra
|
||||||
private void addDummyViews(PopupPopulator.Item[] itemTypesToPopulate,
|
private void addDummyViews(PopupPopulator.Item[] itemTypesToPopulate,
|
||||||
boolean notificationFooterHasIcons) {
|
boolean notificationFooterHasIcons) {
|
||||||
final Resources res = getResources();
|
final Resources res = getResources();
|
||||||
final int spacing = res.getDimensionPixelSize(R.dimen.popup_items_spacing);
|
|
||||||
final LayoutInflater inflater = mLauncher.getLayoutInflater();
|
final LayoutInflater inflater = mLauncher.getLayoutInflater();
|
||||||
|
|
||||||
|
int shortcutsItemRoundedCorners = ROUNDED_TOP_CORNERS | ROUNDED_BOTTOM_CORNERS;
|
||||||
int numItems = itemTypesToPopulate.length;
|
int numItems = itemTypesToPopulate.length;
|
||||||
for (int i = 0; i < numItems; i++) {
|
for (int i = 0; i < numItems; i++) {
|
||||||
PopupPopulator.Item itemTypeToPopulate = itemTypesToPopulate[i];
|
PopupPopulator.Item itemTypeToPopulate = itemTypesToPopulate[i];
|
||||||
|
PopupPopulator.Item prevItemTypeToPopulate =
|
||||||
|
i > 0 ? itemTypesToPopulate[i - 1] : null;
|
||||||
PopupPopulator.Item nextItemTypeToPopulate =
|
PopupPopulator.Item nextItemTypeToPopulate =
|
||||||
i < numItems - 1 ? itemTypesToPopulate[i + 1] : null;
|
i < numItems - 1 ? itemTypesToPopulate[i + 1] : null;
|
||||||
final View item = inflater.inflate(itemTypeToPopulate.layoutId, this, false);
|
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) {
|
if (itemTypeToPopulate == PopupPopulator.Item.NOTIFICATION) {
|
||||||
mNotificationItemView = (NotificationItemView) item;
|
mNotificationItemView = (NotificationItemView) item;
|
||||||
int footerHeight = notificationFooterHasIcons ?
|
int footerHeight = notificationFooterHasIcons ?
|
||||||
res.getDimensionPixelSize(R.dimen.notification_footer_height) : 0;
|
res.getDimensionPixelSize(R.dimen.notification_footer_height) : 0;
|
||||||
item.findViewById(R.id.footer).getLayoutParams().height = footerHeight;
|
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);
|
mNotificationItemView.getMainView().setAccessibilityDelegate(mAccessibilityDelegate);
|
||||||
} else if (itemTypeToPopulate == PopupPopulator.Item.SHORTCUT) {
|
} else if (itemTypeToPopulate == PopupPopulator.Item.SHORTCUT) {
|
||||||
item.setAccessibilityDelegate(mAccessibilityDelegate);
|
item.setAccessibilityDelegate(mAccessibilityDelegate);
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean shouldAddBottomMargin = nextItemTypeToPopulate != null
|
|
||||||
&& itemTypeToPopulate.isShortcut ^ nextItemTypeToPopulate.isShortcut;
|
|
||||||
|
|
||||||
if (itemTypeToPopulate.isShortcut) {
|
if (itemTypeToPopulate.isShortcut) {
|
||||||
if (mShortcutsItemView == null) {
|
if (mShortcutsItemView == null) {
|
||||||
mShortcutsItemView = (ShortcutsItemView) inflater.inflate(
|
mShortcutsItemView = (ShortcutsItemView) inflater.inflate(
|
||||||
R.layout.shortcuts_item, this, false);
|
R.layout.shortcuts_item, this, false);
|
||||||
addView(mShortcutsItemView);
|
addView(mShortcutsItemView);
|
||||||
|
if (shouldUnroundTopCorners) {
|
||||||
|
shortcutsItemRoundedCorners &= ~ROUNDED_TOP_CORNERS;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
mShortcutsItemView.addShortcutView(item, itemTypeToPopulate);
|
mShortcutsItemView.addShortcutView(item, itemTypeToPopulate);
|
||||||
if (shouldAddBottomMargin) {
|
if (shouldUnroundBottomCorners) {
|
||||||
((LayoutParams) mShortcutsItemView.getLayoutParams()).bottomMargin = spacing;
|
shortcutsItemRoundedCorners &= ~ROUNDED_BOTTOM_CORNERS;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
addView(item);
|
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) {
|
protected PopupItemView getItemViewAt(int index) {
|
||||||
|
@ -297,45 +335,31 @@ public class PopupContainerWithArrow extends AbstractFloatingView implements Dra
|
||||||
setVisibility(View.VISIBLE);
|
setVisibility(View.VISIBLE);
|
||||||
mIsOpen = true;
|
mIsOpen = true;
|
||||||
|
|
||||||
final AnimatorSet shortcutAnims = LauncherAnimUtils.createAnimatorSet();
|
final AnimatorSet openAnim = LauncherAnimUtils.createAnimatorSet();
|
||||||
final int itemCount = getItemCount();
|
final Resources res = getResources();
|
||||||
|
|
||||||
final long duration = getResources().getInteger(
|
// Rectangular reveal.
|
||||||
R.integer.config_deepShortcutOpenDuration);
|
int itemsTotalHeight = 0;
|
||||||
final long arrowScaleDuration = getResources().getInteger(
|
for (int i = 0; i < getItemCount(); i++) {
|
||||||
R.integer.config_deepShortcutArrowOpenDuration);
|
itemsTotalHeight += getItemViewAt(i).getMeasuredHeight();
|
||||||
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() {
|
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
|
@Override
|
||||||
public void onAnimationEnd(Animator animation) {
|
public void onAnimationEnd(Animator animation) {
|
||||||
mOpenCloseAnimator = null;
|
mOpenCloseAnimator = null;
|
||||||
|
@ -346,15 +370,26 @@ public class PopupContainerWithArrow extends AbstractFloatingView implements Dra
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Animate the arrow
|
mOpenCloseAnimator = openAnim;
|
||||||
mArrow.setScaleX(0);
|
openAnim.playSequentially(revealAnim, arrowScale);
|
||||||
mArrow.setScaleY(0);
|
openAnim.start();
|
||||||
Animator arrowScale = createArrowScaleAnim(1).setDuration(arrowScaleDuration);
|
}
|
||||||
arrowScale.setStartDelay(arrowScaleDelay);
|
|
||||||
shortcutAnims.play(arrowScale);
|
|
||||||
|
|
||||||
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.
|
// since the latter expects the arrow which hasn't been added yet.
|
||||||
PopupItemView itemAttachedToArrow = (PopupItemView)
|
PopupItemView itemAttachedToArrow = (PopupItemView)
|
||||||
(getChildAt(mIsAboveIcon ? getChildCount() - 1 : 0));
|
(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.
|
// 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);
|
int radius = getResources().getDimensionPixelSize(R.dimen.popup_arrow_corner_radius);
|
||||||
arrowPaint.setPathEffect(new CornerPathEffect(radius));
|
arrowPaint.setPathEffect(new CornerPathEffect(radius));
|
||||||
|
@ -609,22 +644,8 @@ public class PopupContainerWithArrow extends AbstractFloatingView implements Dra
|
||||||
AnimatorSet removeNotification = LauncherAnimUtils.createAnimatorSet();
|
AnimatorSet removeNotification = LauncherAnimUtils.createAnimatorSet();
|
||||||
final int duration = getResources().getInteger(
|
final int duration = getResources().getInteger(
|
||||||
R.integer.config_removeNotificationViewDuration);
|
R.integer.config_removeNotificationViewDuration);
|
||||||
final int spacing = getResources().getDimensionPixelSize(R.dimen.popup_items_spacing);
|
|
||||||
removeNotification.play(reduceNotificationViewHeight(
|
removeNotification.play(reduceNotificationViewHeight(
|
||||||
mNotificationItemView.getHeightMinusFooter() + spacing, duration));
|
mNotificationItemView.getHeightMinusFooter(), 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);
|
|
||||||
}
|
|
||||||
Animator fade = ObjectAnimator.ofFloat(mNotificationItemView, ALPHA, 0)
|
Animator fade = ObjectAnimator.ofFloat(mNotificationItemView, ALPHA, 0)
|
||||||
.setDuration(duration);
|
.setDuration(duration);
|
||||||
fade.addListener(new AnimatorListenerAdapter() {
|
fade.addListener(new AnimatorListenerAdapter() {
|
||||||
|
@ -634,19 +655,25 @@ public class PopupContainerWithArrow extends AbstractFloatingView implements Dra
|
||||||
mNotificationItemView = null;
|
mNotificationItemView = null;
|
||||||
if (getItemCount() == 0) {
|
if (getItemCount() == 0) {
|
||||||
close(false);
|
close(false);
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
removeNotification.play(fade);
|
removeNotification.play(fade);
|
||||||
final long arrowScaleDuration = getResources().getInteger(
|
final long arrowScaleDuration = getResources().getInteger(
|
||||||
R.integer.config_deepShortcutArrowOpenDuration);
|
R.integer.config_popupArrowOpenDuration);
|
||||||
Animator hideArrow = createArrowScaleAnim(0).setDuration(arrowScaleDuration);
|
Animator hideArrow = createArrowScaleAnim(0).setDuration(arrowScaleDuration);
|
||||||
hideArrow.setStartDelay(0);
|
hideArrow.setStartDelay(0);
|
||||||
Animator showArrow = createArrowScaleAnim(1).setDuration(arrowScaleDuration);
|
Animator showArrow = createArrowScaleAnim(1).setDuration(arrowScaleDuration);
|
||||||
showArrow.setStartDelay((long) (duration - arrowScaleDuration * 1.5));
|
showArrow.setStartDelay((long) (duration - arrowScaleDuration * 1.5));
|
||||||
removeNotification.playSequentially(hideArrow, showArrow);
|
removeNotification.playSequentially(hideArrow, showArrow);
|
||||||
removeNotification.start();
|
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;
|
return;
|
||||||
}
|
}
|
||||||
mNotificationItemView.trimNotifications(NotificationKeyData.extractKeysOnly(
|
mNotificationItemView.trimNotifications(NotificationKeyData.extractKeysOnly(
|
||||||
|
@ -770,55 +797,40 @@ public class PopupContainerWithArrow extends AbstractFloatingView implements Dra
|
||||||
if (!mIsOpen) {
|
if (!mIsOpen) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
mEndRect.setEmpty();
|
||||||
if (mOpenCloseAnimator != null) {
|
if (mOpenCloseAnimator != null) {
|
||||||
|
Outline outline = new Outline();
|
||||||
|
getOutlineProvider().getOutline(this, outline);
|
||||||
|
outline.getRect(mEndRect);
|
||||||
mOpenCloseAnimator.cancel();
|
mOpenCloseAnimator.cancel();
|
||||||
}
|
}
|
||||||
mIsOpen = false;
|
mIsOpen = false;
|
||||||
|
|
||||||
final AnimatorSet shortcutAnims = LauncherAnimUtils.createAnimatorSet();
|
final AnimatorSet closeAnim = LauncherAnimUtils.createAnimatorSet();
|
||||||
final int itemCount = getItemCount();
|
final Resources res = getResources();
|
||||||
int numOpenShortcuts = 0;
|
|
||||||
for (int i = 0; i < itemCount; i++) {
|
// Animate the arrow.
|
||||||
if (getItemViewAt(i).isOpenOrOpening()) {
|
Animator arrowScale = createArrowScaleAnim(0).setDuration(res.getInteger(
|
||||||
numOpenShortcuts++;
|
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(
|
Point startPoint = computeAnimStartPoint(itemsTotalHeight);
|
||||||
R.integer.config_deepShortcutCloseDuration);
|
int top = mIsAboveIcon ? getPaddingTop() : startPoint.y;
|
||||||
final long arrowScaleDuration = getResources().getInteger(
|
float radius = getItemViewAt(0).getBackgroundRadius();
|
||||||
R.integer.config_deepShortcutArrowOpenDuration);
|
mStartRect.set(startPoint.x, startPoint.y, startPoint.x, startPoint.y);
|
||||||
final long stagger = getResources().getInteger(
|
if (mEndRect.isEmpty()) {
|
||||||
R.integer.config_deepShortcutCloseStagger);
|
mEndRect.set(0, top, getMeasuredWidth(), top + itemsTotalHeight);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
Animator arrowAnim = createArrowScaleAnim(0).setDuration(arrowScaleDuration);
|
final ValueAnimator revealAnim = new RoundedRectRevealOutlineProvider(
|
||||||
arrowAnim.setStartDelay(0);
|
radius, radius, mStartRect, mEndRect).createRevealAnimator(this, true);
|
||||||
shortcutAnims.play(arrowAnim);
|
revealAnim.setDuration((long) res.getInteger(R.integer.config_popupOpenCloseDuration));
|
||||||
|
revealAnim.setInterpolator(new AccelerateDecelerateInterpolator());
|
||||||
|
|
||||||
shortcutAnims.addListener(new AnimatorListenerAdapter() {
|
closeAnim.addListener(new AnimatorListenerAdapter() {
|
||||||
@Override
|
@Override
|
||||||
public void onAnimationEnd(Animator animation) {
|
public void onAnimationEnd(Animator animation) {
|
||||||
mOpenCloseAnimator = null;
|
mOpenCloseAnimator = null;
|
||||||
|
@ -829,8 +841,9 @@ public class PopupContainerWithArrow extends AbstractFloatingView implements Dra
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
mOpenCloseAnimator = shortcutAnims;
|
mOpenCloseAnimator = closeAnim;
|
||||||
shortcutAnims.start();
|
closeAnim.playSequentially(arrowScale, revealAnim);
|
||||||
|
closeAnim.start();
|
||||||
mOriginalIcon.forceHideBadge(false);
|
mOriginalIcon.forceHideBadge(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -16,38 +16,34 @@
|
||||||
|
|
||||||
package com.android.launcher3.popup;
|
package com.android.launcher3.popup;
|
||||||
|
|
||||||
import android.animation.Animator;
|
|
||||||
import android.animation.AnimatorListenerAdapter;
|
|
||||||
import android.animation.ValueAnimator;
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.graphics.Bitmap;
|
import android.graphics.Bitmap;
|
||||||
import android.graphics.Canvas;
|
import android.graphics.Canvas;
|
||||||
import android.graphics.Matrix;
|
import android.graphics.Matrix;
|
||||||
import android.graphics.Paint;
|
import android.graphics.Paint;
|
||||||
import android.graphics.Point;
|
|
||||||
import android.graphics.PorterDuff;
|
import android.graphics.PorterDuff;
|
||||||
import android.graphics.PorterDuffXfermode;
|
import android.graphics.PorterDuffXfermode;
|
||||||
import android.graphics.Rect;
|
import android.graphics.Rect;
|
||||||
|
import android.graphics.drawable.ShapeDrawable;
|
||||||
|
import android.graphics.drawable.shapes.RoundRectShape;
|
||||||
import android.util.AttributeSet;
|
import android.util.AttributeSet;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.widget.FrameLayout;
|
import android.widget.FrameLayout;
|
||||||
|
|
||||||
import com.android.launcher3.LogAccelerateInterpolator;
|
|
||||||
import com.android.launcher3.R;
|
import com.android.launcher3.R;
|
||||||
import com.android.launcher3.Utilities;
|
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
|
* An abstract {@link FrameLayout} that contains content for {@link PopupContainerWithArrow}.
|
||||||
* (e.g. icon and text) separate from the item's background.
|
|
||||||
*/
|
*/
|
||||||
public abstract class PopupItemView extends FrameLayout
|
public abstract class PopupItemView extends FrameLayout {
|
||||||
implements ValueAnimator.AnimatorUpdateListener {
|
|
||||||
|
|
||||||
protected static final Point sTempPoint = new Point();
|
|
||||||
|
|
||||||
protected final Rect mPillRect;
|
protected final Rect mPillRect;
|
||||||
private float mOpenAnimationProgress;
|
protected @RoundedCornerFlags int mRoundedCorners;
|
||||||
protected final boolean mIsRtl;
|
protected final boolean mIsRtl;
|
||||||
protected View mIconView;
|
protected View mIconView;
|
||||||
|
|
||||||
|
@ -93,164 +89,55 @@ public abstract class PopupItemView extends FrameLayout
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void dispatchDraw(Canvas canvas) {
|
protected void dispatchDraw(Canvas canvas) {
|
||||||
|
if (mRoundedCorners == 0) {
|
||||||
|
super.dispatchDraw(canvas);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
int saveCount = canvas.saveLayer(0, 0, getWidth(), getHeight(), null);
|
int saveCount = canvas.saveLayer(0, 0, getWidth(), getHeight(), null);
|
||||||
super.dispatchDraw(canvas);
|
super.dispatchDraw(canvas);
|
||||||
|
|
||||||
|
// Clip children to this item's rounded corners.
|
||||||
int cornerWidth = mRoundedCornerBitmap.getWidth();
|
int cornerWidth = mRoundedCornerBitmap.getWidth();
|
||||||
int cornerHeight = mRoundedCornerBitmap.getHeight();
|
int cornerHeight = mRoundedCornerBitmap.getHeight();
|
||||||
// Clip top left corner.
|
if ((mRoundedCorners & ROUNDED_TOP_CORNERS) != 0) {
|
||||||
mMatrix.reset();
|
// Clip top left corner.
|
||||||
canvas.drawBitmap(mRoundedCornerBitmap, mMatrix, mBackgroundClipPaint);
|
mMatrix.reset();
|
||||||
// Clip top right corner.
|
canvas.drawBitmap(mRoundedCornerBitmap, mMatrix, mBackgroundClipPaint);
|
||||||
mMatrix.setRotate(90, cornerWidth / 2, cornerHeight / 2);
|
// Clip top right corner.
|
||||||
mMatrix.postTranslate(canvas.getWidth() - cornerWidth, 0);
|
mMatrix.setRotate(90, cornerWidth / 2, cornerHeight / 2);
|
||||||
canvas.drawBitmap(mRoundedCornerBitmap, mMatrix, mBackgroundClipPaint);
|
mMatrix.postTranslate(canvas.getWidth() - cornerWidth, 0);
|
||||||
// Clip bottom right corner.
|
canvas.drawBitmap(mRoundedCornerBitmap, mMatrix, mBackgroundClipPaint);
|
||||||
mMatrix.setRotate(180, cornerWidth / 2, cornerHeight / 2);
|
}
|
||||||
mMatrix.postTranslate(canvas.getWidth() - cornerWidth, canvas.getHeight() - cornerHeight);
|
if ((mRoundedCorners & ROUNDED_BOTTOM_CORNERS) != 0) {
|
||||||
canvas.drawBitmap(mRoundedCornerBitmap, mMatrix, mBackgroundClipPaint);
|
// Clip bottom right corner.
|
||||||
// Clip bottom left corner.
|
mMatrix.setRotate(180, cornerWidth / 2, cornerHeight / 2);
|
||||||
mMatrix.setRotate(270, cornerWidth / 2, cornerHeight / 2);
|
mMatrix.postTranslate(canvas.getWidth() - cornerWidth, canvas.getHeight() - cornerHeight);
|
||||||
mMatrix.postTranslate(0, canvas.getHeight() - cornerHeight);
|
canvas.drawBitmap(mRoundedCornerBitmap, mMatrix, mBackgroundClipPaint);
|
||||||
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);
|
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) {
|
public void setBackgroundWithCorners(int color, @RoundedCornerFlags int roundedCorners) {
|
||||||
Point center = getIconCenter();
|
mRoundedCorners = roundedCorners;
|
||||||
int arrowCenter = getResources().getDimensionPixelSize(pivotLeft ^ mIsRtl ?
|
float rTop = (roundedCorners & ROUNDED_TOP_CORNERS) == 0 ? 0 : getBackgroundRadius();
|
||||||
R.dimen.popup_arrow_horizontal_center_start:
|
float rBot = (roundedCorners & ROUNDED_BOTTOM_CORNERS) == 0 ? 0 : getBackgroundRadius();
|
||||||
R.dimen.popup_arrow_horizontal_center_end);
|
float[] radii = new float[] {rTop, rTop, rTop, rTop, rBot, rBot, rBot, rBot};
|
||||||
ValueAnimator openAnimator = new ZoomRevealOutlineProvider(center.x, center.y,
|
ShapeDrawable roundRectBackground = new ShapeDrawable(new RoundRectShape(radii, null, null));
|
||||||
mPillRect, this, mIconView, isContainerAboveIcon, pivotLeft, arrowCenter)
|
roundRectBackground.getPaint().setColor(color);
|
||||||
.createRevealAnimator(this, false);
|
setBackground(roundRectBackground);
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected float getBackgroundRadius() {
|
protected float getBackgroundRadius() {
|
||||||
return getResources().getDimensionPixelSize(R.dimen.bg_round_rect_radius);
|
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,12 +16,10 @@
|
||||||
|
|
||||||
package com.android.launcher3.shortcuts;
|
package com.android.launcher3.shortcuts;
|
||||||
|
|
||||||
import android.animation.Animator;
|
|
||||||
import android.animation.AnimatorSet;
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.graphics.Point;
|
import android.graphics.Point;
|
||||||
import android.support.v4.content.ContextCompat;
|
|
||||||
import android.util.AttributeSet;
|
import android.util.AttributeSet;
|
||||||
|
import android.view.LayoutInflater;
|
||||||
import android.view.MotionEvent;
|
import android.view.MotionEvent;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.widget.LinearLayout;
|
import android.widget.LinearLayout;
|
||||||
|
@ -30,9 +28,7 @@ import com.android.launcher3.AbstractFloatingView;
|
||||||
import com.android.launcher3.BubbleTextView;
|
import com.android.launcher3.BubbleTextView;
|
||||||
import com.android.launcher3.ItemInfo;
|
import com.android.launcher3.ItemInfo;
|
||||||
import com.android.launcher3.Launcher;
|
import com.android.launcher3.Launcher;
|
||||||
import com.android.launcher3.LauncherAnimUtils;
|
|
||||||
import com.android.launcher3.R;
|
import com.android.launcher3.R;
|
||||||
import com.android.launcher3.anim.PropertyListBuilder;
|
|
||||||
import com.android.launcher3.dragndrop.DragOptions;
|
import com.android.launcher3.dragndrop.DragOptions;
|
||||||
import com.android.launcher3.dragndrop.DragView;
|
import com.android.launcher3.dragndrop.DragView;
|
||||||
import com.android.launcher3.logging.UserEventDispatcher.LogContainerProvider;
|
import com.android.launcher3.logging.UserEventDispatcher.LogContainerProvider;
|
||||||
|
@ -135,7 +131,17 @@ public class ShortcutsItemView extends PopupItemView implements View.OnLongClick
|
||||||
if (mSystemShortcutIcons == null) {
|
if (mSystemShortcutIcons == null) {
|
||||||
mSystemShortcutIcons = (LinearLayout) mLauncher.getLayoutInflater().inflate(
|
mSystemShortcutIcons = (LinearLayout) mLauncher.getLayoutInflater().inflate(
|
||||||
R.layout.system_shortcut_icons, mShortcutsLayout, false);
|
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);
|
mSystemShortcutIcons.addView(shortcutView, index);
|
||||||
} else {
|
} else {
|
||||||
|
@ -209,51 +215,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
|
@Override
|
||||||
public void fillInLogContainerData(View v, ItemInfo info, LauncherLogProto.Target target,
|
public void fillInLogContainerData(View v, ItemInfo info, LauncherLogProto.Target target,
|
||||||
LauncherLogProto.Target targetParent) {
|
LauncherLogProto.Target targetParent) {
|
||||||
|
|
Loading…
Reference in New Issue