diff --git a/src/com/android/launcher3/dragndrop/AddItemActivity.java b/src/com/android/launcher3/dragndrop/AddItemActivity.java index 6bd62617fb..92ed18af06 100644 --- a/src/com/android/launcher3/dragndrop/AddItemActivity.java +++ b/src/com/android/launcher3/dragndrop/AddItemActivity.java @@ -192,15 +192,15 @@ public class AddItemActivity extends BaseActivity float appWidgetHostViewScale = mWidgetCell.getAppWidgetHostViewScale(); int xOffset = appWidgetHostView.getLeft() - (int) (mLastTouchPos.x * appWidgetHostViewScale); - int yOffset = appWidgetHostView.getTop() - - (int) (mLastTouchPos.y * mWidgetCell.getAppWidgetHostViewScale()); + int yOffset = + appWidgetHostView.getTop() - (int) (mLastTouchPos.y * appWidgetHostViewScale); bounds.offset(xOffset, yOffset); listener = new PinItemDragListener( mRequest, bounds, appWidgetHostView.getMeasuredWidth(), appWidgetHostView.getMeasuredWidth(), - appWidgetHostView.getScaleX()); + appWidgetHostViewScale); } else { bounds = img.getBitmapBounds(); bounds.offset(img.getLeft() - (int) mLastTouchPos.x, diff --git a/src/com/android/launcher3/widget/BaseWidgetSheet.java b/src/com/android/launcher3/widget/BaseWidgetSheet.java index ee441747ac..8e9769c6e2 100644 --- a/src/com/android/launcher3/widget/BaseWidgetSheet.java +++ b/src/com/android/launcher3/widget/BaseWidgetSheet.java @@ -188,11 +188,11 @@ public abstract class BaseWidgetSheet extends AbstractSlideInView dragHelper.startDrag(image.getBitmapBounds(), image.getDrawable().getIntrinsicWidth(), image.getWidth(), new Point(loc[0], loc[1]), this, new DragOptions()); } else { - View preview = v.getAppWidgetHostViewPreview(); + NavigableAppWidgetHostView preview = v.getAppWidgetHostViewPreview(); int[] loc = new int[2]; getPopupContainer().getLocationInDragLayer(preview, loc); - - Rect r = new Rect(0, 0, preview.getWidth(), preview.getHeight()); + Rect r = new Rect(); + preview.getWorkspaceVisualDragBounds(r); dragHelper.startDrag(r, preview.getMeasuredWidth(), preview.getMeasuredWidth(), new Point(loc[0], loc[1]), this, new DragOptions()); } diff --git a/src/com/android/launcher3/widget/LauncherAppWidgetHostView.java b/src/com/android/launcher3/widget/LauncherAppWidgetHostView.java index fb6de9fb5e..0313e68bcb 100644 --- a/src/com/android/launcher3/widget/LauncherAppWidgetHostView.java +++ b/src/com/android/launcher3/widget/LauncherAppWidgetHostView.java @@ -84,10 +84,8 @@ public class LauncherAppWidgetHostView extends BaseLauncherAppWidgetHostView private boolean mIsScrollable; private boolean mIsAttachedToWindow; private boolean mIsAutoAdvanceRegistered; - private boolean mIsInDragMode = false; private Runnable mAutoAdvanceRunnable; private RectF mLastLocationRegistered = null; - @Nullable private AppWidgetHostViewDragListener mDragListener; // Used to store the widget sizes in drag layer coordinates. private final Rect mCurrentWidgetSize = new Rect(); @@ -102,6 +100,14 @@ public class LauncherAppWidgetHostView extends BaseLauncherAppWidgetHostView private @Nullable SparseIntArray mDeferredColorChange = null; private boolean mEnableColorExtraction = true; + // The following member variables are only used during drag-n-drop. + private boolean mIsInDragMode = false; + @Nullable private AppWidgetHostViewDragListener mDragListener; + /** The drag content width which is only set when the drag content scale is not 1f. */ + private int mDragContentWidth = 0; + /** The drag content height which is only set when the drag content scale is not 1f. */ + private int mDragContentHeight = 0; + public LauncherAppWidgetHostView(Context context) { super(context); mLauncher = Launcher.getLauncher(context); @@ -310,10 +316,28 @@ public class LauncherAppWidgetHostView extends BaseLauncherAppWidgetHostView updateColorExtraction(); } + @Override + protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { + super.onMeasure(widthMeasureSpec, heightMeasureSpec); + if (mIsInDragMode && mDragContentWidth > 0 && mDragContentHeight > 0 + && getChildCount() == 1) { + measureChild(getChildAt(0), MeasureSpec.getSize(mDragContentWidth), + MeasureSpec.getSize(mDragContentHeight)); + } + } + /** Starts the drag mode. */ public void startDrag(AppWidgetHostViewDragListener dragListener) { mIsInDragMode = true; mDragListener = dragListener; + // In the case of dragging a scaled preview from widgets picker, we should reuse the + // previously measured dimension from WidgetCell#measureAndComputeWidgetPreviewScale, which + // measures the dimension of a widget preview without its parent's bound before scaling + // down. + if ((getScaleX() != 1f || getScaleY() != 1f) && getChildCount() == 1) { + mDragContentWidth = getChildAt(0).getMeasuredWidth(); + mDragContentHeight = getChildAt(0).getMeasuredHeight(); + } } /** Handles a drag event occurred on a workspace page, {@code pageId}. */ @@ -326,6 +350,8 @@ public class LauncherAppWidgetHostView extends BaseLauncherAppWidgetHostView public void endDrag() { mIsInDragMode = false; mDragListener = null; + mDragContentWidth = 0; + mDragContentHeight = 0; mWidgetSizeAtDrag.setEmpty(); } diff --git a/src/com/android/launcher3/widget/WidgetCell.java b/src/com/android/launcher3/widget/WidgetCell.java index d3f45282de..167eb0983e 100644 --- a/src/com/android/launcher3/widget/WidgetCell.java +++ b/src/com/android/launcher3/widget/WidgetCell.java @@ -18,6 +18,7 @@ package com.android.launcher3.widget; import static android.view.View.MeasureSpec.makeMeasureSpec; import static android.view.ViewGroup.LayoutParams.MATCH_PARENT; +import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT; import static com.android.launcher3.LauncherSettings.Favorites.CONTAINER_WIDGETS_TRAY; import static com.android.launcher3.Utilities.ATLEAST_S; @@ -372,7 +373,7 @@ public class WidgetCell extends LinearLayout implements OnLayoutChangeListener { if (shouldScale) { setNoClip(mWidgetImageContainer); setNoClip(mAppWidgetHostViewPreview); - mAppWidgetHostViewScale = computeWidgetPreviewScale(); + mAppWidgetHostViewScale = measureAndComputeWidgetPreviewScale(); mAppWidgetHostViewPreview.setScaleToFit(mAppWidgetHostViewScale); } } @@ -473,7 +474,7 @@ public class WidgetCell extends LinearLayout implements OnLayoutChangeListener { view.setClipToPadding(false); } - private float computeWidgetPreviewScale() { + private float measureAndComputeWidgetPreviewScale() { if (mAppWidgetHostViewPreview.getChildCount() != 1) { return 1f; } @@ -482,12 +483,25 @@ public class WidgetCell extends LinearLayout implements OnLayoutChangeListener { mAppWidgetHostViewPreview.measure( makeMeasureSpec(MAX_MEASURE_SPEC_DIMENSION, MeasureSpec.UNSPECIFIED), makeMeasureSpec(MAX_MEASURE_SPEC_DIMENSION, MeasureSpec.UNSPECIFIED)); - int appWidgetContentWidth = mAppWidgetHostViewPreview.getChildAt(0).getMeasuredWidth(); - int appWidgetContentHeight = mAppWidgetHostViewPreview.getChildAt(0).getMeasuredHeight(); + View widgetContent = mAppWidgetHostViewPreview.getChildAt(0); + int appWidgetContentWidth = widgetContent.getMeasuredWidth(); + int appWidgetContentHeight = widgetContent.getMeasuredHeight(); if (appWidgetContentWidth == 0 || appWidgetContentHeight == 0) { return 1f; } + // If the width / height of the widget content is set to wrap content, overrides the width / + // height with the measured dimension. This avoids incorrect measurement after scaling. + FrameLayout.LayoutParams layoutParam = + (FrameLayout.LayoutParams) widgetContent.getLayoutParams(); + if (layoutParam.width == WRAP_CONTENT) { + layoutParam.width = widgetContent.getMeasuredWidth(); + } + if (layoutParam.height == WRAP_CONTENT) { + layoutParam.height = widgetContent.getMeasuredHeight(); + } + widgetContent.setLayoutParams(layoutParam); + int horizontalPadding = mAppWidgetHostViewPreview.getPaddingStart() + mAppWidgetHostViewPreview.getPaddingEnd(); int verticalPadding = mAppWidgetHostViewPreview.getPaddingTop()