Merge "Merge deep shortcuts in rounded rect" into ub-launcher3-dorval
This commit is contained in:
@@ -1,24 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- 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.
|
||||
-->
|
||||
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:state_focused="true">
|
||||
<shape android:shape="rectangle">
|
||||
<stroke android:color="?android:attr/colorControlActivated" android:width="2dp" />
|
||||
<corners android:radius="@dimen/bg_pill_radius" />
|
||||
</shape>
|
||||
</item>
|
||||
</selector>
|
||||
@@ -1,21 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- 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.
|
||||
-->
|
||||
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shape="rectangle">
|
||||
<solid android:color="#FFFFFF" />
|
||||
<corners android:radius="@dimen/bg_pill_radius" />
|
||||
</shape>
|
||||
@@ -17,18 +17,16 @@
|
||||
<com.android.launcher3.shortcuts.DeepShortcutView
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:launcher="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="@dimen/bg_pill_width"
|
||||
android:layout_height="@dimen/bg_pill_height"
|
||||
android:elevation="@dimen/deep_shortcuts_elevation"
|
||||
android:background="@drawable/bg_white_pill" >
|
||||
android:layout_width="@dimen/bg_popup_item_width"
|
||||
android:layout_height="@dimen/bg_popup_item_height" >
|
||||
|
||||
<com.android.launcher3.shortcuts.DeepShortcutTextView
|
||||
style="@style/BaseIcon"
|
||||
android:id="@+id/deep_shortcut"
|
||||
android:background="@drawable/bg_pill_focused"
|
||||
android:background="?android:attr/selectableItemBackground"
|
||||
android:gravity="start|center_vertical"
|
||||
android:textAlignment="viewStart"
|
||||
android:paddingStart="@dimen/bg_pill_height"
|
||||
android:paddingStart="@dimen/bg_popup_item_height"
|
||||
android:paddingEnd="@dimen/deep_shortcut_padding_end"
|
||||
android:drawableEnd="@drawable/deep_shortcuts_drag_handle"
|
||||
android:drawablePadding="@dimen/deep_shortcut_drawable_padding"
|
||||
@@ -40,10 +38,18 @@
|
||||
android:elevation="@dimen/deep_shortcuts_elevation" />
|
||||
|
||||
<View
|
||||
android:id="@+id/popup_item_icon"
|
||||
android:id="@+id/icon"
|
||||
android:layout_width="@dimen/deep_shortcut_icon_size"
|
||||
android:layout_height="@dimen/deep_shortcut_icon_size"
|
||||
android:layout_margin="@dimen/deep_shortcut_padding_start"
|
||||
android:layout_gravity="start" />
|
||||
|
||||
<View
|
||||
android:id="@+id/divider"
|
||||
android:layout_width="@dimen/deep_shortcuts_divider_width"
|
||||
android:layout_height="@dimen/popup_item_divider_height"
|
||||
android:layout_gravity="end|bottom"
|
||||
android:visibility="gone"
|
||||
android:background="?android:attr/listDivider" />
|
||||
|
||||
</com.android.launcher3.shortcuts.DeepShortcutView>
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
<com.android.launcher3.notification.NotificationItemView
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/notification_view"
|
||||
android:layout_width="@dimen/bg_pill_width"
|
||||
android:layout_width="@dimen/bg_popup_item_width"
|
||||
android:layout_height="wrap_content"
|
||||
android:elevation="@dimen/deep_shortcuts_elevation"
|
||||
android:background="@drawable/bg_white_round_rect">
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
<View
|
||||
android:id="@+id/divider"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/notification_divider_height"/>
|
||||
android:layout_height="@dimen/popup_item_divider_height"/>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/icon_row"
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
<?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.
|
||||
-->
|
||||
|
||||
<com.android.launcher3.shortcuts.ShortcutsItemView
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/shortcuts_view"
|
||||
android:layout_width="@dimen/bg_popup_item_width"
|
||||
android:layout_height="wrap_content"
|
||||
android:elevation="@dimen/deep_shortcuts_elevation"
|
||||
android:background="@drawable/bg_white_round_rect">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/deep_shortcuts"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical">
|
||||
</LinearLayout>
|
||||
|
||||
</com.android.launcher3.shortcuts.ShortcutsItemView>
|
||||
@@ -150,10 +150,9 @@
|
||||
|
||||
<!-- Deep shortcuts -->
|
||||
<dimen name="deep_shortcuts_elevation">9dp</dimen>
|
||||
<dimen name="bg_pill_width">208dp</dimen>
|
||||
<dimen name="bg_pill_height">48dp</dimen>
|
||||
<dimen name="bg_pill_radius">24dp</dimen>
|
||||
<dimen name="deep_shortcuts_spacing">4dp</dimen>
|
||||
<dimen name="bg_popup_item_width">208dp</dimen>
|
||||
<dimen name="bg_popup_item_height">48dp</dimen>
|
||||
<dimen name="popup_items_spacing">4dp</dimen>
|
||||
<dimen name="pre_drag_view_scale">6dp</dimen>
|
||||
<!-- an icon with shortcuts must be dragged this far before the container is removed. -->
|
||||
<dimen name="deep_shortcuts_start_drag_threshold">16dp</dimen>
|
||||
@@ -171,6 +170,8 @@
|
||||
deep_shortcut_padding_end + deep_shortcut_drag_handle_size / 2 - deep_shortcuts_arrow_width / 2
|
||||
also happens to equal 19dp-->
|
||||
<dimen name="deep_shortcuts_arrow_horizontal_offset">19dp</dimen>
|
||||
<!-- popup_item_width - icon_size - padding_start - drawable_padding -->
|
||||
<dimen name="deep_shortcuts_divider_width">158dp</dimen>
|
||||
|
||||
<!-- Icon badges (with notification counts) -->
|
||||
<dimen name="badge_size">24dp</dimen>
|
||||
@@ -186,9 +187,9 @@
|
||||
<!-- (icon_size - footer_icon_size) / 2 -->
|
||||
<dimen name="notification_footer_icon_row_padding">2dp</dimen>
|
||||
<dimen name="notification_main_height">60dp</dimen>
|
||||
<dimen name="notification_footer_height">@dimen/bg_pill_height</dimen>
|
||||
<dimen name="notification_footer_height">@dimen/bg_popup_item_height</dimen>
|
||||
<dimen name="notification_elevation">2dp</dimen>
|
||||
<dimen name="notification_divider_height">0.5dp</dimen>
|
||||
<dimen name="popup_item_divider_height">0.5dp</dimen>
|
||||
<dimen name="swipe_helper_falsing_threshold">70dp</dimen>
|
||||
|
||||
<!-- Other -->
|
||||
|
||||
@@ -95,7 +95,7 @@ public abstract class AbstractFloatingView extends LinearLayout {
|
||||
return null;
|
||||
}
|
||||
|
||||
protected static void closeOpenContainer(Launcher launcher, @FloatingViewType int type) {
|
||||
public static void closeOpenContainer(Launcher launcher, @FloatingViewType int type) {
|
||||
AbstractFloatingView view = getOpenView(launcher, type);
|
||||
if (view != null) {
|
||||
view.close(true);
|
||||
|
||||
@@ -22,7 +22,6 @@ import android.graphics.Bitmap;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.RectF;
|
||||
import android.graphics.Shader;
|
||||
import android.support.annotation.Nullable;
|
||||
|
||||
|
||||
@@ -20,14 +20,7 @@ import android.animation.Animator;
|
||||
import android.animation.AnimatorListenerAdapter;
|
||||
import android.content.Context;
|
||||
import android.content.res.ColorStateList;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.BitmapShader;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.PorterDuff;
|
||||
import android.graphics.PorterDuffXfermode;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.Shader;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
@@ -36,11 +29,11 @@ import android.widget.FrameLayout;
|
||||
|
||||
import com.android.launcher3.ItemInfo;
|
||||
import com.android.launcher3.R;
|
||||
import com.android.launcher3.anim.PillHeightRevealOutlineProvider;
|
||||
import com.android.launcher3.graphics.IconPalette;
|
||||
import com.android.launcher3.logging.UserEventDispatcher.LogContainerProvider;
|
||||
import com.android.launcher3.popup.PopupItemView;
|
||||
import com.android.launcher3.userevent.nano.LauncherLogProto;
|
||||
import com.android.launcher3.anim.PillHeightRevealOutlineProvider;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@@ -54,9 +47,6 @@ public class NotificationItemView extends PopupItemView implements LogContainerP
|
||||
|
||||
private static final Rect sTempRect = new Rect();
|
||||
|
||||
private final Paint mBackgroundClipPaint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.DITHER_FLAG |
|
||||
Paint.FILTER_BITMAP_FLAG);
|
||||
|
||||
private View mDivider;
|
||||
private NotificationMainView mMainView;
|
||||
private NotificationFooterLayout mFooter;
|
||||
@@ -85,35 +75,6 @@ public class NotificationItemView extends PopupItemView implements LogContainerP
|
||||
mSwipeHelper.setDisableHardwareLayers(true);
|
||||
}
|
||||
|
||||
private void initializeBackgroundClipping(boolean force) {
|
||||
if (force || mBackgroundClipPaint.getShader() == null) {
|
||||
mBackgroundClipPaint.setXfermode(null);
|
||||
mBackgroundClipPaint.setShader(null);
|
||||
Bitmap backgroundBitmap = Bitmap.createBitmap(getMeasuredWidth(), getMeasuredHeight(),
|
||||
Bitmap.Config.ALPHA_8);
|
||||
Canvas canvas = new Canvas();
|
||||
canvas.setBitmap(backgroundBitmap);
|
||||
float roundRectRadius = getResources().getDimensionPixelSize(
|
||||
R.dimen.bg_round_rect_radius);
|
||||
canvas.drawRoundRect(0, 0, getMeasuredWidth(), getMeasuredHeight(),
|
||||
roundRectRadius, roundRectRadius, mBackgroundClipPaint);
|
||||
Shader backgroundClipShader = new BitmapShader(backgroundBitmap,
|
||||
Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
|
||||
mBackgroundClipPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));
|
||||
mBackgroundClipPaint.setShader(backgroundClipShader);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void dispatchDraw(Canvas canvas) {
|
||||
initializeBackgroundClipping(false /* force */);
|
||||
int saveCount = canvas.saveLayer(0, 0, getWidth(), getHeight(), null,
|
||||
Canvas.HAS_ALPHA_LAYER_SAVE_FLAG | Canvas.CLIP_TO_LAYER_SAVE_FLAG);
|
||||
super.dispatchDraw(canvas);
|
||||
canvas.drawPaint(mBackgroundClipPaint);
|
||||
canvas.restoreToCount(saveCount);
|
||||
}
|
||||
|
||||
public Animator animateHeightRemoval(int heightToRemove) {
|
||||
final int newHeight = getHeight() - heightToRemove;
|
||||
Animator heightAnimator = new PillHeightRevealOutlineProvider(mPillRect,
|
||||
@@ -134,11 +95,6 @@ public class NotificationItemView extends PopupItemView implements LogContainerP
|
||||
return heightAnimator;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected float getBackgroundRadius() {
|
||||
return getResources().getDimensionPixelSize(R.dimen.bg_round_rect_radius);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onInterceptTouchEvent(MotionEvent ev) {
|
||||
if (mMainView.getNotificationInfo() == null) {
|
||||
|
||||
@@ -22,7 +22,9 @@ import android.animation.ArgbEvaluator;
|
||||
import android.animation.ObjectAnimator;
|
||||
import android.animation.ValueAnimator;
|
||||
import android.content.Context;
|
||||
import android.content.res.ColorStateList;
|
||||
import android.graphics.drawable.ColorDrawable;
|
||||
import android.graphics.drawable.RippleDrawable;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
@@ -71,7 +73,9 @@ public class NotificationMainView extends LinearLayout implements SwipeHelper.Ca
|
||||
|
||||
public void applyColors(IconPalette iconPalette) {
|
||||
mColorBackground = new ColorDrawable(iconPalette.backgroundColor);
|
||||
setBackground(mColorBackground);
|
||||
RippleDrawable rippleDrawable = new RippleDrawable(ColorStateList.valueOf(
|
||||
iconPalette.secondaryColor), mColorBackground, null);
|
||||
setBackground(rippleDrawable);
|
||||
mIconPalette = iconPalette;
|
||||
}
|
||||
|
||||
|
||||
@@ -27,7 +27,6 @@ import android.annotation.TargetApi;
|
||||
import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.Point;
|
||||
import android.graphics.PointF;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.drawable.ShapeDrawable;
|
||||
@@ -64,15 +63,13 @@ 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.IconPalette;
|
||||
import com.android.launcher3.graphics.TriangleShape;
|
||||
import com.android.launcher3.notification.NotificationItemView;
|
||||
import com.android.launcher3.shortcuts.DeepShortcutView;
|
||||
import com.android.launcher3.shortcuts.ShortcutDragPreviewProvider;
|
||||
import com.android.launcher3.shortcuts.ShortcutsItemView;
|
||||
import com.android.launcher3.util.PackageUserKey;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@@ -84,18 +81,17 @@ import static com.android.launcher3.userevent.nano.LauncherLogProto.Target;
|
||||
* A container for shortcuts to deep links within apps.
|
||||
*/
|
||||
@TargetApi(Build.VERSION_CODES.N)
|
||||
public class PopupContainerWithArrow extends AbstractFloatingView
|
||||
implements View.OnLongClickListener, View.OnTouchListener, DragSource,
|
||||
public class PopupContainerWithArrow extends AbstractFloatingView implements DragSource,
|
||||
DragController.DragListener {
|
||||
|
||||
private final Point mIconShift = new Point();
|
||||
private final Point mIconLastTouchPos = new Point();
|
||||
|
||||
protected final Launcher mLauncher;
|
||||
private final int mStartDragThreshold;
|
||||
private LauncherAccessibilityDelegate mAccessibilityDelegate;
|
||||
private final boolean mIsRtl;
|
||||
|
||||
public ShortcutsItemView mShortcutsItemView;
|
||||
private NotificationItemView mNotificationItemView;
|
||||
|
||||
protected BubbleTextView mOriginalIcon;
|
||||
private final Rect mTempRect = new Rect();
|
||||
private PointF mInterceptTouchDown = new PointF();
|
||||
@@ -177,6 +173,8 @@ public class PopupContainerWithArrow extends AbstractFloatingView
|
||||
boolean reverseOrder = mIsAboveIcon;
|
||||
if (reverseOrder) {
|
||||
removeAllViews();
|
||||
mNotificationItemView = null;
|
||||
mShortcutsItemView = null;
|
||||
itemsToPopulate = PopupPopulator.reverseItems(itemsToPopulate);
|
||||
addDummyViews(originalIcon, itemsToPopulate, notificationKeys.length > 1);
|
||||
|
||||
@@ -184,22 +182,12 @@ public class PopupContainerWithArrow extends AbstractFloatingView
|
||||
orientAboutIcon(originalIcon, arrowHeight + arrowVerticalOffset);
|
||||
}
|
||||
|
||||
List<DeepShortcutView> shortcutViews = new ArrayList<>();
|
||||
NotificationItemView notificationView = null;
|
||||
for (int i = 0; i < getChildCount(); i++) {
|
||||
View item = getChildAt(i);
|
||||
List<DeepShortcutView> shortcutViews = mShortcutsItemView.getDeepShortcutViews(reverseOrder);
|
||||
for (int i = 0; i < itemsToPopulate.length; i++) {
|
||||
switch (itemsToPopulate[i]) {
|
||||
case SHORTCUT:
|
||||
if (reverseOrder) {
|
||||
shortcutViews.add(0, (DeepShortcutView) item);
|
||||
} else {
|
||||
shortcutViews.add((DeepShortcutView) item);
|
||||
}
|
||||
break;
|
||||
case NOTIFICATION:
|
||||
notificationView = (NotificationItemView) item;
|
||||
IconPalette iconPalette = originalIcon.getIconPalette();
|
||||
notificationView.applyColors(iconPalette);
|
||||
mNotificationItemView.applyColors(iconPalette);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -221,28 +209,46 @@ public class PopupContainerWithArrow extends AbstractFloatingView
|
||||
final Looper workerLooper = LauncherModel.getWorkerLooper();
|
||||
new Handler(workerLooper).postAtFrontOfQueue(PopupPopulator.createUpdateRunnable(
|
||||
mLauncher, (ItemInfo) originalIcon.getTag(), new Handler(Looper.getMainLooper()),
|
||||
this, shortcutIds, shortcutViews, notificationKeys, notificationView));
|
||||
this, shortcutIds, shortcutViews, notificationKeys, mNotificationItemView));
|
||||
}
|
||||
|
||||
private void addDummyViews(BubbleTextView originalIcon,
|
||||
PopupPopulator.Item[] itemsToPopulate, boolean notificationFooterHasIcons) {
|
||||
PopupPopulator.Item[] itemTypesToPopulate, boolean notificationFooterHasIcons) {
|
||||
final Resources res = getResources();
|
||||
final int spacing = res.getDimensionPixelSize(R.dimen.deep_shortcuts_spacing);
|
||||
final int spacing = res.getDimensionPixelSize(R.dimen.popup_items_spacing);
|
||||
final LayoutInflater inflater = mLauncher.getLayoutInflater();
|
||||
int numItems = itemsToPopulate.length;
|
||||
int numItems = itemTypesToPopulate.length;
|
||||
for (int i = 0; i < numItems; i++) {
|
||||
final PopupItemView item = (PopupItemView) inflater.inflate(
|
||||
itemsToPopulate[i].layoutId, this, false);
|
||||
if (itemsToPopulate[i] == PopupPopulator.Item.NOTIFICATION) {
|
||||
PopupPopulator.Item itemTypeToPopulate = itemTypesToPopulate[i];
|
||||
final View item = inflater.inflate(itemTypeToPopulate.layoutId, this, false);
|
||||
|
||||
if (itemTypeToPopulate == PopupPopulator.Item.NOTIFICATION) {
|
||||
mNotificationItemView = (NotificationItemView) item;
|
||||
int footerHeight = notificationFooterHasIcons ?
|
||||
res.getDimensionPixelSize(R.dimen.notification_footer_height) : 0;
|
||||
item.findViewById(R.id.footer).getLayoutParams().height = footerHeight;
|
||||
}
|
||||
if (i < numItems - 1) {
|
||||
((LayoutParams) item.getLayoutParams()).bottomMargin = spacing;
|
||||
}
|
||||
|
||||
boolean itemIsFollowedByDifferentType = i < numItems - 1
|
||||
&& itemTypesToPopulate[i + 1] != itemTypeToPopulate;
|
||||
|
||||
item.setAccessibilityDelegate(mAccessibilityDelegate);
|
||||
addView(item);
|
||||
if (itemTypeToPopulate == PopupPopulator.Item.SHORTCUT) {
|
||||
if (mShortcutsItemView == null) {
|
||||
mShortcutsItemView = (ShortcutsItemView) inflater.inflate(
|
||||
R.layout.shortcuts_item, this, false);
|
||||
addView(mShortcutsItemView);
|
||||
}
|
||||
mShortcutsItemView.addDeepShortcutView((DeepShortcutView) item);
|
||||
if (itemIsFollowedByDifferentType) {
|
||||
((LayoutParams) mShortcutsItemView.getLayoutParams()).bottomMargin = spacing;
|
||||
}
|
||||
} else {
|
||||
addView(item);
|
||||
if (itemIsFollowedByDifferentType) {
|
||||
((LayoutParams) item.getLayoutParams()).bottomMargin = spacing;
|
||||
}
|
||||
}
|
||||
}
|
||||
// TODO: update this, since not all items are shortcuts
|
||||
setContentDescription(getContext().getString(R.string.shortcuts_menu_description,
|
||||
@@ -534,49 +540,8 @@ public class PopupContainerWithArrow extends AbstractFloatingView
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onTouch(View v, MotionEvent ev) {
|
||||
// Touched a shortcut, update where it was touched so we can drag from there on long click.
|
||||
switch (ev.getAction()) {
|
||||
case MotionEvent.ACTION_DOWN:
|
||||
case MotionEvent.ACTION_MOVE:
|
||||
mIconLastTouchPos.set((int) ev.getX(), (int) ev.getY());
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean onLongClick(View v) {
|
||||
// Return early if this is not initiated from a touch or not the correct view
|
||||
if (!v.isInTouchMode() || !(v.getParent() instanceof DeepShortcutView)) return false;
|
||||
// Return early if global dragging is not enabled
|
||||
if (!mLauncher.isDraggingEnabled()) return false;
|
||||
// Return early if an item is already being dragged (e.g. when long-pressing two shortcuts)
|
||||
if (mLauncher.getDragController().isDragging()) return false;
|
||||
|
||||
// Long clicked on a shortcut.
|
||||
mDeferContainerRemoval = true;
|
||||
DeepShortcutView sv = (DeepShortcutView) v.getParent();
|
||||
sv.setWillDrawIcon(false);
|
||||
|
||||
// Move the icon to align with the center-top of the touch point
|
||||
mIconShift.x = mIconLastTouchPos.x - sv.getIconCenter().x;
|
||||
mIconShift.y = mIconLastTouchPos.y - mLauncher.getDeviceProfile().iconSizePx;
|
||||
|
||||
DragView dv = mLauncher.getWorkspace().beginDragShared(
|
||||
sv.getBubbleText(), this, sv.getFinalInfo(),
|
||||
new ShortcutDragPreviewProvider(sv.getIconView(), mIconShift), new DragOptions());
|
||||
dv.animateShift(-mIconShift.x, -mIconShift.y);
|
||||
|
||||
// TODO: support dragging from within folder without having to close it
|
||||
AbstractFloatingView.closeOpenContainer(mLauncher, AbstractFloatingView.TYPE_FOLDER);
|
||||
return false;
|
||||
}
|
||||
|
||||
public void trimNotifications(Map<PackageUserKey, BadgeInfo> updatedBadges) {
|
||||
final NotificationItemView notificationView =
|
||||
(NotificationItemView) findViewById(R.id.notification_view);
|
||||
if (notificationView == null) {
|
||||
if (mNotificationItemView == null) {
|
||||
return;
|
||||
}
|
||||
ItemInfo originalInfo = (ItemInfo) mOriginalIcon.getTag();
|
||||
@@ -585,11 +550,11 @@ public class PopupContainerWithArrow extends AbstractFloatingView
|
||||
AnimatorSet removeNotification = LauncherAnimUtils.createAnimatorSet();
|
||||
final int duration = getResources().getInteger(
|
||||
R.integer.config_removeNotificationViewDuration);
|
||||
final int spacing = getResources().getDimensionPixelSize(R.dimen.deep_shortcuts_spacing);
|
||||
final int spacing = getResources().getDimensionPixelSize(R.dimen.popup_items_spacing);
|
||||
removeNotification.play(reduceNotificationViewHeight(
|
||||
notificationView.getHeight() + spacing, duration, notificationView));
|
||||
mNotificationItemView.getHeight() + spacing, duration, mNotificationItemView));
|
||||
final View removeMarginView = mIsAboveIcon ? getItemViewAt(getItemCount() - 2)
|
||||
: notificationView;
|
||||
: mNotificationItemView;
|
||||
if (removeMarginView != null) {
|
||||
ValueAnimator removeMargin = ValueAnimator.ofFloat(1, 0).setDuration(duration);
|
||||
removeMargin.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
|
||||
@@ -601,12 +566,12 @@ public class PopupContainerWithArrow extends AbstractFloatingView
|
||||
});
|
||||
removeNotification.play(removeMargin);
|
||||
}
|
||||
Animator fade = ObjectAnimator.ofFloat(notificationView, ALPHA, 0)
|
||||
Animator fade = ObjectAnimator.ofFloat(mNotificationItemView, ALPHA, 0)
|
||||
.setDuration(duration);
|
||||
fade.addListener(new AnimatorListenerAdapter() {
|
||||
@Override
|
||||
public void onAnimationEnd(Animator animation) {
|
||||
removeView(notificationView);
|
||||
removeView(mNotificationItemView);
|
||||
if (getItemCount() == 0) {
|
||||
close(false);
|
||||
return;
|
||||
@@ -626,7 +591,7 @@ public class PopupContainerWithArrow extends AbstractFloatingView
|
||||
removeNotification.start();
|
||||
return;
|
||||
}
|
||||
notificationView.trimNotifications(badgeInfo.getNotificationKeys());
|
||||
mNotificationItemView.trimNotifications(badgeInfo.getNotificationKeys());
|
||||
}
|
||||
|
||||
private ObjectAnimator createArrowScaleAnim(float scale) {
|
||||
@@ -669,8 +634,7 @@ public class PopupContainerWithArrow extends AbstractFloatingView
|
||||
}
|
||||
|
||||
public Animator reduceNotificationViewHeight(int heightToRemove, int duration) {
|
||||
return reduceNotificationViewHeight(heightToRemove, duration,
|
||||
(NotificationItemView) findViewById(R.id.notification_view));
|
||||
return reduceNotificationViewHeight(heightToRemove, duration, mNotificationItemView);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -702,6 +666,7 @@ public class PopupContainerWithArrow extends AbstractFloatingView
|
||||
public void onDragStart(DropTarget.DragObject dragObject, DragOptions options) {
|
||||
// Either the original icon or one of the shortcuts was dragged.
|
||||
// Hide the container, but don't remove it yet because that interferes with touch events.
|
||||
mDeferContainerRemoval = true;
|
||||
animateClose();
|
||||
}
|
||||
|
||||
@@ -723,7 +688,6 @@ public class PopupContainerWithArrow extends AbstractFloatingView
|
||||
@Override
|
||||
public void fillInLogContainerData(View v, ItemInfo info, Target target, Target targetParent) {
|
||||
target.itemType = ItemType.DEEPSHORTCUT;
|
||||
target.rank = info.rank;
|
||||
targetParent.containerType = ContainerType.DEEPSHORTCUTS;
|
||||
}
|
||||
|
||||
@@ -765,38 +729,17 @@ public class PopupContainerWithArrow extends AbstractFloatingView
|
||||
for (int i = firstOpenItemIndex; i < firstOpenItemIndex + numOpenShortcuts; i++) {
|
||||
final PopupItemView view = getItemViewAt(i);
|
||||
Animator anim;
|
||||
if (view.willDrawIcon()) {
|
||||
anim = view.createCloseAnimation(mIsAboveIcon, mIsLeftAligned, duration);
|
||||
int animationIndex = mIsAboveIcon ? i - firstOpenItemIndex
|
||||
: numOpenShortcuts - i - 1;
|
||||
anim.setStartDelay(stagger * animationIndex);
|
||||
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);
|
||||
} else {
|
||||
// The view is being dragged. Animate it such that it collapses with the drag view
|
||||
anim = view.collapseToIcon();
|
||||
anim.setDuration(DragView.VIEW_ZOOM_DURATION);
|
||||
|
||||
// Scale and translate the view to follow the drag view.
|
||||
Point iconCenter = view.getIconCenter();
|
||||
view.setPivotX(iconCenter.x);
|
||||
view.setPivotY(iconCenter.y);
|
||||
|
||||
float scale = ((float) mLauncher.getDeviceProfile().iconSizePx) / view.getHeight();
|
||||
Animator anim2 = LauncherAnimUtils.ofPropertyValuesHolder(view,
|
||||
new PropertyListBuilder()
|
||||
.scale(scale)
|
||||
.translationX(mIconShift.x)
|
||||
.translationY(mIconShift.y)
|
||||
.build())
|
||||
.setDuration(DragView.VIEW_ZOOM_DURATION);
|
||||
shortcutAnims.play(anim2);
|
||||
}
|
||||
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) {
|
||||
|
||||
@@ -21,8 +21,15 @@ import android.animation.AnimatorListenerAdapter;
|
||||
import android.animation.ValueAnimator;
|
||||
import android.content.Context;
|
||||
import android.content.res.ColorStateList;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.BitmapShader;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.Point;
|
||||
import android.graphics.PorterDuff;
|
||||
import android.graphics.PorterDuffXfermode;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.Shader;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.View;
|
||||
import android.widget.FrameLayout;
|
||||
@@ -31,7 +38,6 @@ import com.android.launcher3.LogAccelerateInterpolator;
|
||||
import com.android.launcher3.R;
|
||||
import com.android.launcher3.Utilities;
|
||||
import com.android.launcher3.util.PillRevealOutlineProvider;
|
||||
import com.android.launcher3.util.PillWidthRevealOutlineProvider;
|
||||
|
||||
/**
|
||||
* An abstract {@link FrameLayout} that supports animating an item's content
|
||||
@@ -47,6 +53,9 @@ public abstract class PopupItemView extends FrameLayout
|
||||
|
||||
protected View mIconView;
|
||||
|
||||
private final Paint mBackgroundClipPaint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.DITHER_FLAG |
|
||||
Paint.FILTER_BITMAP_FLAG);
|
||||
|
||||
public PopupItemView(Context context) {
|
||||
this(context, null, 0);
|
||||
}
|
||||
@@ -73,12 +82,35 @@ public abstract class PopupItemView extends FrameLayout
|
||||
mPillRect.set(0, 0, getMeasuredWidth(), getMeasuredHeight());
|
||||
}
|
||||
|
||||
protected ColorStateList getAttachedArrowColor() {
|
||||
return getBackgroundTintList();
|
||||
protected void initializeBackgroundClipping(boolean force) {
|
||||
if (force || mBackgroundClipPaint.getShader() == null) {
|
||||
mBackgroundClipPaint.setXfermode(null);
|
||||
mBackgroundClipPaint.setShader(null);
|
||||
Bitmap backgroundBitmap = Bitmap.createBitmap(getMeasuredWidth(), getMeasuredHeight(),
|
||||
Bitmap.Config.ALPHA_8);
|
||||
Canvas canvas = new Canvas();
|
||||
canvas.setBitmap(backgroundBitmap);
|
||||
canvas.drawRoundRect(0, 0, getMeasuredWidth(), getMeasuredHeight(),
|
||||
getBackgroundRadius(), getBackgroundRadius(), mBackgroundClipPaint);
|
||||
Shader backgroundClipShader = new BitmapShader(backgroundBitmap,
|
||||
Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
|
||||
mBackgroundClipPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));
|
||||
mBackgroundClipPaint.setShader(backgroundClipShader);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean willDrawIcon() {
|
||||
return true;
|
||||
@Override
|
||||
protected void dispatchDraw(Canvas canvas) {
|
||||
initializeBackgroundClipping(false /* force */);
|
||||
int saveCount = canvas.saveLayer(0, 0, getWidth(), getHeight(), null,
|
||||
Canvas.HAS_ALPHA_LAYER_SAVE_FLAG | Canvas.CLIP_TO_LAYER_SAVE_FLAG);
|
||||
super.dispatchDraw(canvas);
|
||||
canvas.drawPaint(mBackgroundClipPaint);
|
||||
canvas.restoreToCount(saveCount);
|
||||
}
|
||||
|
||||
protected ColorStateList getAttachedArrowColor() {
|
||||
return getBackgroundTintList();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -125,17 +157,6 @@ public abstract class PopupItemView extends FrameLayout
|
||||
return closeAnimator;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an animator which clips the container to form a circle around the icon.
|
||||
*/
|
||||
public Animator collapseToIcon() {
|
||||
int halfHeight = getMeasuredHeight() / 2;
|
||||
int iconCenterX = getIconCenter().x;
|
||||
return new PillWidthRevealOutlineProvider(mPillRect,
|
||||
iconCenterX - halfHeight, iconCenterX + halfHeight)
|
||||
.createRevealAnimator(this, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the position of the center of the icon relative to the container.
|
||||
*/
|
||||
@@ -148,7 +169,7 @@ public abstract class PopupItemView extends FrameLayout
|
||||
}
|
||||
|
||||
protected float getBackgroundRadius() {
|
||||
return getResources().getDimensionPixelSize(R.dimen.bg_pill_radius);
|
||||
return getResources().getDimensionPixelSize(R.dimen.bg_round_rect_radius);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -182,8 +203,10 @@ public abstract class PopupItemView extends FrameLayout
|
||||
public void setProgress(float progress) {
|
||||
super.setProgress(progress);
|
||||
|
||||
mZoomView.setScaleX(progress);
|
||||
mZoomView.setScaleY(progress);
|
||||
if (mZoomView != null) {
|
||||
mZoomView.setScaleX(progress);
|
||||
mZoomView.setScaleY(progress);
|
||||
}
|
||||
|
||||
float height = mOutline.height();
|
||||
mTranslateView.setTranslationY(mTranslateYMultiplier * (mFullHeight - height));
|
||||
|
||||
@@ -196,7 +196,8 @@ public class PopupPopulator {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
mShortcutChild.applyShortcutInfo(mShortcutChildInfo, mDetail, mContainer);
|
||||
mShortcutChild.applyShortcutInfo(mShortcutChildInfo, mDetail,
|
||||
mContainer.mShortcutsItemView);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -17,26 +17,30 @@
|
||||
package com.android.launcher3.shortcuts;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Point;
|
||||
import android.graphics.Rect;
|
||||
import android.text.TextUtils;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.View;
|
||||
import android.widget.FrameLayout;
|
||||
|
||||
import com.android.launcher3.Launcher;
|
||||
import com.android.launcher3.R;
|
||||
import com.android.launcher3.ShortcutInfo;
|
||||
import com.android.launcher3.popup.PopupContainerWithArrow;
|
||||
import com.android.launcher3.popup.PopupItemView;
|
||||
import com.android.launcher3.Utilities;
|
||||
|
||||
/**
|
||||
* A {@link android.widget.FrameLayout} that contains a {@link DeepShortcutView}.
|
||||
* This lets us animate the DeepShortcutView (icon and text) separately from the background.
|
||||
*/
|
||||
public class DeepShortcutView extends PopupItemView {
|
||||
public class DeepShortcutView extends FrameLayout {
|
||||
|
||||
private static final Point sTempPoint = new Point();
|
||||
|
||||
private final Rect mPillRect;
|
||||
|
||||
private DeepShortcutTextView mBubbleText;
|
||||
private View mIconView;
|
||||
|
||||
private ShortcutInfo mInfo;
|
||||
private ShortcutInfoCompat mDetail;
|
||||
@@ -59,6 +63,7 @@ public class DeepShortcutView extends PopupItemView {
|
||||
protected void onFinishInflate() {
|
||||
super.onFinishInflate();
|
||||
mBubbleText = (DeepShortcutTextView) findViewById(R.id.deep_shortcut);
|
||||
mIconView = findViewById(R.id.icon);
|
||||
}
|
||||
|
||||
public DeepShortcutTextView getBubbleText() {
|
||||
@@ -73,6 +78,17 @@ public class DeepShortcutView extends PopupItemView {
|
||||
return mIconView.getVisibility() == View.VISIBLE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the position of the center of the icon relative to the container.
|
||||
*/
|
||||
public Point getIconCenter() {
|
||||
sTempPoint.y = sTempPoint.x = getMeasuredHeight() / 2;
|
||||
if (Utilities.isRtl(getResources())) {
|
||||
sTempPoint.x = getMeasuredWidth() - sTempPoint.x;
|
||||
}
|
||||
return sTempPoint;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
||||
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
|
||||
@@ -81,7 +97,7 @@ public class DeepShortcutView extends PopupItemView {
|
||||
|
||||
/** package private **/
|
||||
public void applyShortcutInfo(ShortcutInfo info, ShortcutInfoCompat detail,
|
||||
PopupContainerWithArrow container) {
|
||||
ShortcutsItemView container) {
|
||||
mInfo = info;
|
||||
mDetail = detail;
|
||||
mBubbleText.applyFromShortcutInfo(info);
|
||||
|
||||
@@ -0,0 +1,180 @@
|
||||
/*
|
||||
* 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.shortcuts;
|
||||
|
||||
import android.animation.Animator;
|
||||
import android.animation.AnimatorSet;
|
||||
import android.content.Context;
|
||||
import android.graphics.Point;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.widget.LinearLayout;
|
||||
|
||||
import com.android.launcher3.AbstractFloatingView;
|
||||
import com.android.launcher3.ItemInfo;
|
||||
import com.android.launcher3.Launcher;
|
||||
import com.android.launcher3.LauncherAnimUtils;
|
||||
import com.android.launcher3.R;
|
||||
import com.android.launcher3.anim.PropertyListBuilder;
|
||||
import com.android.launcher3.dragndrop.DragOptions;
|
||||
import com.android.launcher3.dragndrop.DragView;
|
||||
import com.android.launcher3.logging.UserEventDispatcher.LogContainerProvider;
|
||||
import com.android.launcher3.popup.PopupContainerWithArrow;
|
||||
import com.android.launcher3.popup.PopupItemView;
|
||||
import com.android.launcher3.userevent.nano.LauncherLogProto;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* A {@link PopupItemView} that contains all of the {@link DeepShortcutView}s for an app.
|
||||
*/
|
||||
public class ShortcutsItemView extends PopupItemView implements View.OnLongClickListener,
|
||||
View.OnTouchListener, LogContainerProvider {
|
||||
|
||||
private Launcher mLauncher;
|
||||
private LinearLayout mDeepShortcutsLayout;
|
||||
private final Point mIconShift = new Point();
|
||||
private final Point mIconLastTouchPos = new Point();
|
||||
|
||||
public ShortcutsItemView(Context context) {
|
||||
this(context, null, 0);
|
||||
}
|
||||
|
||||
public ShortcutsItemView(Context context, AttributeSet attrs) {
|
||||
this(context, attrs, 0);
|
||||
}
|
||||
|
||||
public ShortcutsItemView(Context context, AttributeSet attrs, int defStyle) {
|
||||
super(context, attrs, defStyle);
|
||||
|
||||
mLauncher = Launcher.getLauncher(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onFinishInflate() {
|
||||
super.onFinishInflate();
|
||||
mDeepShortcutsLayout = (LinearLayout) findViewById(R.id.deep_shortcuts);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onTouch(View v, MotionEvent ev) {
|
||||
// Touched a shortcut, update where it was touched so we can drag from there on long click.
|
||||
switch (ev.getAction()) {
|
||||
case MotionEvent.ACTION_DOWN:
|
||||
case MotionEvent.ACTION_MOVE:
|
||||
mIconLastTouchPos.set((int) ev.getX(), (int) ev.getY());
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onLongClick(View v) {
|
||||
// Return early if this is not initiated from a touch or not the correct view
|
||||
if (!v.isInTouchMode() || !(v.getParent() instanceof DeepShortcutView)) return false;
|
||||
// Return early if global dragging is not enabled
|
||||
if (!mLauncher.isDraggingEnabled()) return false;
|
||||
// Return early if an item is already being dragged (e.g. when long-pressing two shortcuts)
|
||||
if (mLauncher.getDragController().isDragging()) return false;
|
||||
|
||||
// Long clicked on a shortcut.
|
||||
DeepShortcutView sv = (DeepShortcutView) v.getParent();
|
||||
sv.setWillDrawIcon(false);
|
||||
|
||||
// Move the icon to align with the center-top of the touch point
|
||||
mIconShift.x = mIconLastTouchPos.x - sv.getIconCenter().x;
|
||||
mIconShift.y = mIconLastTouchPos.y - mLauncher.getDeviceProfile().iconSizePx;
|
||||
|
||||
DragView dv = mLauncher.getWorkspace().beginDragShared(sv.getBubbleText(),
|
||||
(PopupContainerWithArrow) getParent(), sv.getFinalInfo(),
|
||||
new ShortcutDragPreviewProvider(sv.getIconView(), mIconShift), new DragOptions());
|
||||
dv.animateShift(-mIconShift.x, -mIconShift.y);
|
||||
|
||||
// TODO: support dragging from within folder without having to close it
|
||||
AbstractFloatingView.closeOpenContainer(mLauncher, AbstractFloatingView.TYPE_FOLDER);
|
||||
return false;
|
||||
}
|
||||
|
||||
public void addDeepShortcutView(DeepShortcutView deepShortcutView) {
|
||||
if (getNumDeepShortcuts() > 0) {
|
||||
getDeepShortcutAt(getNumDeepShortcuts() - 1).findViewById(R.id.divider)
|
||||
.setVisibility(VISIBLE);
|
||||
}
|
||||
mDeepShortcutsLayout.addView(deepShortcutView);
|
||||
}
|
||||
|
||||
private DeepShortcutView getDeepShortcutAt(int index) {
|
||||
return (DeepShortcutView) mDeepShortcutsLayout.getChildAt(index);
|
||||
}
|
||||
|
||||
private int getNumDeepShortcuts() {
|
||||
return mDeepShortcutsLayout.getChildCount();
|
||||
}
|
||||
|
||||
public List<DeepShortcutView> getDeepShortcutViews(boolean reverseOrder) {
|
||||
int numDeepShortcuts = getNumDeepShortcuts();
|
||||
List<DeepShortcutView> deepShortcutViews = new ArrayList<>(numDeepShortcuts);
|
||||
for (int i = 0; i < numDeepShortcuts; i++) {
|
||||
DeepShortcutView deepShortcut = getDeepShortcutAt(i);
|
||||
if (reverseOrder) {
|
||||
deepShortcutViews.add(0, deepShortcut);
|
||||
} else {
|
||||
deepShortcutViews.add(deepShortcut);
|
||||
}
|
||||
}
|
||||
return deepShortcutViews;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Animator createOpenAnimation(boolean isContainerAboveIcon, boolean pivotLeft) {
|
||||
AnimatorSet openAnimation = LauncherAnimUtils.createAnimatorSet();
|
||||
openAnimation.play(super.createOpenAnimation(isContainerAboveIcon, pivotLeft));
|
||||
for (int i = 0; i < getNumDeepShortcuts(); i++) {
|
||||
View deepShortcutIcon = getDeepShortcutAt(i).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 < getNumDeepShortcuts(); i++) {
|
||||
View deepShortcutIcon = getDeepShortcutAt(i).getIconView();
|
||||
deepShortcutIcon.setScaleX(1);
|
||||
deepShortcutIcon.setScaleY(1);
|
||||
closeAnimation.play(LauncherAnimUtils.ofPropertyValuesHolder(
|
||||
deepShortcutIcon, new PropertyListBuilder().scale(0).build()));
|
||||
}
|
||||
return closeAnimation;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fillInLogContainerData(View v, ItemInfo info, LauncherLogProto.Target target,
|
||||
LauncherLogProto.Target targetParent) {
|
||||
target.itemType = LauncherLogProto.ItemType.DEEPSHORTCUT;
|
||||
target.rank = info.rank;
|
||||
targetParent.containerType = LauncherLogProto.ContainerType.DEEPSHORTCUTS;
|
||||
}
|
||||
}
|
||||
@@ -1,41 +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.util;
|
||||
|
||||
import android.graphics.Rect;
|
||||
|
||||
/**
|
||||
* Extension of {@link PillRevealOutlineProvider} which only changes the width of the pill.
|
||||
*/
|
||||
public class PillWidthRevealOutlineProvider extends PillRevealOutlineProvider {
|
||||
|
||||
private final int mStartLeft;
|
||||
private final int mStartRight;
|
||||
|
||||
public PillWidthRevealOutlineProvider(Rect pillRect, int left, int right) {
|
||||
super(0, 0, pillRect);
|
||||
mOutline.set(pillRect);
|
||||
mStartLeft = left;
|
||||
mStartRight = right;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setProgress(float progress) {
|
||||
mOutline.left = (int) (progress * mPillRect.left + (1 - progress) * mStartLeft);
|
||||
mOutline.right = (int) (progress * mPillRect.right + (1 - progress) * mStartRight);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user