diff --git a/src/com/android/launcher3/CellLayout.java b/src/com/android/launcher3/CellLayout.java index bb83802d2a..c3816ccf0c 100644 --- a/src/com/android/launcher3/CellLayout.java +++ b/src/com/android/launcher3/CellLayout.java @@ -61,7 +61,6 @@ import com.android.launcher3.LauncherSettings.Favorites; import com.android.launcher3.accessibility.DragAndDropAccessibilityDelegate; import com.android.launcher3.anim.Interpolators; import com.android.launcher3.config.FeatureFlags; -import com.android.launcher3.dragndrop.AppWidgetHostViewDrawable; import com.android.launcher3.folder.PreviewBackground; import com.android.launcher3.model.data.ItemInfo; import com.android.launcher3.util.CellAndSpan; @@ -70,6 +69,7 @@ import com.android.launcher3.util.ParcelableSparseArray; import com.android.launcher3.util.Themes; import com.android.launcher3.util.Thunk; import com.android.launcher3.views.ActivityContext; +import com.android.launcher3.widget.LauncherAppWidgetHostView; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; @@ -1065,15 +1065,14 @@ public class CellLayout extends ViewGroup { private void applyColorExtractionOnWidget(DropTarget.DragObject dragObject, int[] targetCell, int spanX, int spanY) { // Apply local extracted color if the DragView is an AppWidgetHostViewDrawable. - Drawable drawable = dragObject.dragView.getDrawable(); - if (drawable instanceof AppWidgetHostViewDrawable) { + View view = dragObject.dragView.getContentView(); + if (view instanceof LauncherAppWidgetHostView) { Workspace workspace = Launcher.getLauncher(dragObject.dragView.getContext()).getWorkspace(); int screenId = workspace.getIdForScreen(this); int pageId = workspace.getPageIndexForScreenId(screenId); - AppWidgetHostViewDrawable hostViewDrawable = ((AppWidgetHostViewDrawable) drawable); cellToRect(targetCell[0], targetCell[1], spanX, spanY, mTempRect); - hostViewDrawable.getAppWidgetHostView().handleDrag(mTempRect, pageId); + ((LauncherAppWidgetHostView) view).handleDrag(mTempRect, pageId); } } diff --git a/src/com/android/launcher3/Workspace.java b/src/com/android/launcher3/Workspace.java index 1931c29754..10091a18b8 100644 --- a/src/com/android/launcher3/Workspace.java +++ b/src/com/android/launcher3/Workspace.java @@ -69,7 +69,6 @@ import com.android.launcher3.anim.Interpolators; import com.android.launcher3.anim.PendingAnimation; import com.android.launcher3.config.FeatureFlags; import com.android.launcher3.dot.FolderDotInfo; -import com.android.launcher3.dragndrop.AppWidgetHostViewDrawable; import com.android.launcher3.dragndrop.DragController; import com.android.launcher3.dragndrop.DragLayer; import com.android.launcher3.dragndrop.DragOptions; @@ -414,7 +413,9 @@ public class Workspace extends PagedView } if (mDragInfo != null && mDragInfo.cell != null) { - CellLayout layout = (CellLayout) mDragInfo.cell.getParent().getParent(); + CellLayout layout = (CellLayout) (mDragInfo.cell instanceof LauncherAppWidgetHostView + ? dragObject.dragView.getContentViewParent().getParent() + : mDragInfo.cell.getParent().getParent()); layout.markCellsAsUnoccupiedForView(mDragInfo.cell); } @@ -1527,10 +1528,19 @@ public class Workspace extends PagedView draggableView = (DraggableView) child; } + final View contentView = previewProvider.getContentView(); + final float scale; // The draggable drawable follows the touch point around on the screen - final Drawable drawable = previewProvider.createDrawable(); + final Drawable drawable; + if (contentView == null) { + drawable = previewProvider.createDrawable(); + scale = previewProvider.getScaleAndPosition(drawable, mTempXY); + } else { + drawable = null; + scale = previewProvider.getScaleAndPosition(contentView, mTempXY); + } + int halfPadding = previewProvider.previewPadding / 2; - float scale = previewProvider.getScaleAndPosition(drawable, mTempXY); int dragLayerX = mTempXY[0]; int dragLayerY = mTempXY[1]; @@ -1556,21 +1566,37 @@ public class Workspace extends PagedView } } - if (drawable instanceof AppWidgetHostViewDrawable) { - mDragController.addDragListener(new AppWidgetHostViewDragListener(mLauncher)); + final DragView dv; + if (contentView instanceof View) { + if (contentView instanceof LauncherAppWidgetHostView) { + mDragController.addDragListener(new AppWidgetHostViewDragListener(mLauncher)); + } + dv = mDragController.startDrag( + contentView, + draggableView, + dragLayerX, + dragLayerY, + source, + dragObject, + dragVisualizeOffset, + dragRect, + scale * iconScale, + scale, + dragOptions); + } else { + dv = mDragController.startDrag( + drawable, + draggableView, + dragLayerX, + dragLayerY, + source, + dragObject, + dragVisualizeOffset, + dragRect, + scale * iconScale, + scale, + dragOptions); } - DragView dv = mDragController.startDrag( - drawable, - draggableView, - dragLayerX, - dragLayerY, - source, - dragObject, - dragVisualizeOffset, - dragRect, - scale * iconScale, - scale, - dragOptions); return dv; } @@ -1900,6 +1926,8 @@ public class Workspace extends PagedView CellLayout parentCell = getParentCellLayoutForView(cell); if (parentCell != null) { parentCell.removeView(cell); + } else if (mDragInfo.cell instanceof LauncherAppWidgetHostView) { + d.dragView.detachContentView(/* reattachToPreviousParent= */ false); } else if (FeatureFlags.IS_STUDIO_BUILD) { throw new NullPointerException("mDragInfo.cell has null parent"); } @@ -1938,6 +1966,9 @@ public class Workspace extends PagedView if (!returnToOriginalCellToPreventShuffling) { onNoCellFound(dropTargetLayout); } + if (mDragInfo.cell instanceof LauncherAppWidgetHostView) { + d.dragView.detachContentView(/* reattachToPreviousParent= */ true); + } // If we can't find a drop location, we return the item to its original position CellLayout.LayoutParams lp = (CellLayout.LayoutParams) cell.getLayoutParams(); @@ -2636,10 +2667,6 @@ public class Workspace extends PagedView } private Drawable createWidgetDrawable(ItemInfo widgetInfo, View layout) { - if (layout instanceof LauncherAppWidgetHostView) { - return new AppWidgetHostViewDrawable((LauncherAppWidgetHostView) layout); - } - int[] unScaledSize = estimateItemSize(widgetInfo); int visibility = layout.getVisibility(); layout.setVisibility(VISIBLE); @@ -2720,7 +2747,9 @@ public class Workspace extends PagedView boolean isWidget = info.itemType == LauncherSettings.Favorites.ITEM_TYPE_APPWIDGET || info.itemType == LauncherSettings.Favorites.ITEM_TYPE_CUSTOM_APPWIDGET; - if ((animationType == ANIMATE_INTO_POSITION_AND_RESIZE || external) && finalView != null) { + if ((animationType == ANIMATE_INTO_POSITION_AND_RESIZE || external) + && finalView != null + && dragView.getContentView() != finalView) { Drawable crossFadeDrawable = createWidgetDrawable(info, finalView); dragView.crossFadeContent(crossFadeDrawable, (int) (duration * 0.8f)); } else if (isWidget && external) { diff --git a/src/com/android/launcher3/dragndrop/AppWidgetHostViewDrawable.java b/src/com/android/launcher3/dragndrop/AppWidgetHostViewDrawable.java deleted file mode 100644 index 2135f5dff9..0000000000 --- a/src/com/android/launcher3/dragndrop/AppWidgetHostViewDrawable.java +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright (C) 2021 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.dragndrop; - -import android.graphics.Canvas; -import android.graphics.ColorFilter; -import android.graphics.Paint; -import android.graphics.PixelFormat; -import android.graphics.drawable.Drawable; - -import com.android.launcher3.widget.LauncherAppWidgetHostView; - -/** - * A drawable which renders {@link LauncherAppWidgetHostView} to a canvas. - * - * TODO(b/183609936) Stop using that class and remove it. - */ -public final class AppWidgetHostViewDrawable extends Drawable { - - private final LauncherAppWidgetHostView mAppWidgetHostView; - private Paint mPaint = new Paint(); - - public AppWidgetHostViewDrawable(LauncherAppWidgetHostView appWidgetHostView) { - mAppWidgetHostView = appWidgetHostView; - } - - @Override - public void draw(Canvas canvas) { - int saveCount = canvas.saveLayer(0, 0, getIntrinsicWidth(), getIntrinsicHeight(), mPaint); - mAppWidgetHostView.draw(canvas); - canvas.restoreToCount(saveCount); - } - - @Override - public int getIntrinsicWidth() { - return mAppWidgetHostView.getMeasuredWidth(); - } - - @Override - public int getIntrinsicHeight() { - return mAppWidgetHostView.getMeasuredHeight(); - } - - @Override - public int getOpacity() { - // This is up to app widget provider. We don't know if the host view will cover anything - // behind the drawable. - return PixelFormat.UNKNOWN; - } - - @Override - public void setAlpha(int alpha) { - mPaint.setAlpha(alpha); - } - - @Override - public int getAlpha() { - return mPaint.getAlpha(); - } - - @Override - public void setColorFilter(ColorFilter colorFilter) { - mPaint.setColorFilter(colorFilter); - } - - @Override - public ColorFilter getColorFilter() { - return mPaint.getColorFilter(); - } - - /** Returns the {@link LauncherAppWidgetHostView}. */ - public LauncherAppWidgetHostView getAppWidgetHostView() { - return mAppWidgetHostView; - } -} diff --git a/src/com/android/launcher3/dragndrop/DragController.java b/src/com/android/launcher3/dragndrop/DragController.java index b7a70cb654..d7f6cdb8bb 100644 --- a/src/com/android/launcher3/dragndrop/DragController.java +++ b/src/com/android/launcher3/dragndrop/DragController.java @@ -34,6 +34,8 @@ import android.view.KeyEvent; import android.view.MotionEvent; import android.view.View; +import androidx.annotation.Nullable; + import com.android.launcher3.AbstractFloatingView; import com.android.launcher3.DragSource; import com.android.launcher3.DropTarget; @@ -125,20 +127,23 @@ public class DragController implements DragDriver.EventListener, TouchController /** * Starts a drag. - * When the drag is started, the UI automatically goes into spring loaded mode. On a successful - * drop, it is the responsibility of the {@link DropTarget} to exit out of the spring loaded - * mode. If the drop was cancelled for some reason, the UI will automatically exit out of this mode. + * + *

When the drag is started, the UI automatically goes into spring loaded mode. On a + * successful drop, it is the responsibility of the {@link DropTarget} to exit out of the spring + * loaded mode. If the drop was cancelled for some reason, the UI will automatically exit out of + * this mode. * * @param drawable The drawable to be displayed in the drag view. It will be re-scaled to the - * enlarged size. - * @param originalView The source view (ie. icon, widget etc.) that is being dragged - * and which the DragView represents + * enlarged size. + * @param originalView The source view (ie. icon, widget etc.) that is being dragged and which + * the DragView represents * @param dragLayerX The x position in the DragLayer of the left-top of the bitmap. * @param dragLayerY The y position in the DragLayer of the left-top of the bitmap. * @param source An object representing where the drag originated * @param dragInfo The data associated with the object that is being dragged * @param dragRegion Coordinates within the bitmap b for the position of item being dragged. - * Makes dragging feel more precise, e.g. you can clip out a transparent border + * Makes dragging feel more precise, e.g. you can clip out a transparent + * border */ public DragView startDrag( Drawable drawable, @@ -152,6 +157,61 @@ public class DragController implements DragDriver.EventListener, TouchController float initialDragViewScale, float dragViewScaleOnDrop, DragOptions options) { + return startDrag(drawable, /* view= */ null, originalView, dragLayerX, dragLayerY, + source, dragInfo, dragOffset, dragRegion, initialDragViewScale, dragViewScaleOnDrop, + options); + } + + /** + * Starts a drag. + * + *

When the drag is started, the UI automatically goes into spring loaded mode. On a + * successful drop, it is the responsibility of the {@link DropTarget} to exit out of the spring + * loaded mode. If the drop was cancelled for some reason, the UI will automatically exit out of + * this mode. + * + * @param view The view to be displayed in the drag view. It will be re-scaled to the + * enlarged size. + * @param originalView The source view (ie. icon, widget etc.) that is being dragged and which + * the DragView represents + * @param dragLayerX The x position in the DragLayer of the left-top of the bitmap. + * @param dragLayerY The y position in the DragLayer of the left-top of the bitmap. + * @param source An object representing where the drag originated + * @param dragInfo The data associated with the object that is being dragged + * @param dragRegion Coordinates within the bitmap b for the position of item being dragged. + * Makes dragging feel more precise, e.g. you can clip out a transparent + * border + */ + public DragView startDrag( + View view, + DraggableView originalView, + int dragLayerX, + int dragLayerY, + DragSource source, + ItemInfo dragInfo, + Point dragOffset, + Rect dragRegion, + float initialDragViewScale, + float dragViewScaleOnDrop, + DragOptions options) { + return startDrag(/* drawable= */ null, view, originalView, dragLayerX, dragLayerY, + source, dragInfo, dragOffset, dragRegion, initialDragViewScale, dragViewScaleOnDrop, + options); + } + + private DragView startDrag( + @Nullable Drawable drawable, + @Nullable View view, + DraggableView originalView, + int dragLayerX, + int dragLayerY, + DragSource source, + ItemInfo dragInfo, + Point dragOffset, + Rect dragRegion, + float initialDragViewScale, + float dragViewScaleOnDrop, + DragOptions options) { if (PROFILE_DRAWING_DURING_DRAG) { android.os.Debug.startMethodTracing("Launcher"); } @@ -182,14 +242,25 @@ public class DragController implements DragDriver.EventListener, TouchController final Resources res = mLauncher.getResources(); final float scaleDps = mIsInPreDrag ? res.getDimensionPixelSize(R.dimen.pre_drag_view_scale) : 0f; - final DragView dragView = mDragObject.dragView = new DragView( - mLauncher, - drawable, - registrationX, - registrationY, - initialDragViewScale, - dragViewScaleOnDrop, - scaleDps); + final DragView dragView = mDragObject.dragView = drawable != null + ? new DragView( + mLauncher, + drawable, + registrationX, + registrationY, + initialDragViewScale, + dragViewScaleOnDrop, + scaleDps) + : new DragView( + mLauncher, + view, + view.getMeasuredWidth(), + view.getMeasuredHeight(), + registrationX, + registrationY, + initialDragViewScale, + dragViewScaleOnDrop, + scaleDps); dragView.setItemInfo(dragInfo); mDragObject.dragComplete = false; diff --git a/src/com/android/launcher3/dragndrop/DragView.java b/src/com/android/launcher3/dragndrop/DragView.java index 346359954e..68a8af238e 100644 --- a/src/com/android/launcher3/dragndrop/DragView.java +++ b/src/com/android/launcher3/dragndrop/DragView.java @@ -42,9 +42,11 @@ import android.os.Build; import android.os.Handler; import android.os.Looper; import android.view.View; +import android.view.ViewGroup; import android.widget.FrameLayout; import android.widget.ImageView; +import androidx.annotation.Nullable; import androidx.dynamicanimation.animation.FloatPropertyCompat; import androidx.dynamicanimation.animation.SpringAnimation; import androidx.dynamicanimation.animation.SpringForce; @@ -69,6 +71,10 @@ public class DragView extends FrameLayout implements StateListenerIn the case of no change in the drop position, sets {@code reattachToPreviousParent} to + * {@code true} to attach the {@link #mContent} back to its previous parent. + */ + public void detachContentView(boolean reattachToPreviousParent) { + if (mContent != null && mContentViewParent != null && mContentViewInParentViewIndex >= 0) { + removeView(mContent); + mContent.setLayoutParams(mContentViewLayoutParams); + if (reattachToPreviousParent) { + mContentViewParent.addView(mContent, mContentViewInParentViewIndex); + } + mContentViewParent = null; + mContentViewInParentViewIndex = -1; + } + } + + /** + * Removes this view from the {@link DragLayer}. + * + *

If the drag content is a {@link #mContent}, this call doesn't reattach the + * {@link #mContent} back to its previous parent. To reattach to previous parent, the caller + * should call {@link #detachContentView} with {@code reattachToPreviousParent} sets to true + * before this call. + */ public void remove() { if (getParent() != null) { mDragLayer.removeView(DragView.this); @@ -449,9 +495,18 @@ public class DragView extends FrameLayout implements StateListener drawDragView(c, scale))); } + /** + * Returns the content view if the content should be rendered directly in + * {@link com.android.launcher3.dragndrop.DragView}. Otherwise, returns null. + */ + @Nullable + public View getContentView() { + if (mView instanceof LauncherAppWidgetHostView) { + return mView; + } + return null; + } + public final void generateDragOutline(Bitmap preview) { if (FeatureFlags.IS_STUDIO_BUILD && mOutlineGeneratorCallback != null) { throw new RuntimeException("Drag outline generated twice"); @@ -152,6 +165,22 @@ public class DragPreviewProvider { return scale; } + /** Returns the scale and position of a given view for drag-n-drop. */ + public float getScaleAndPosition(View view, int[] outPos) { + float scale = Launcher.getLauncher(mView.getContext()) + .getDragLayer().getLocationInDragLayer(mView, outPos); + if (mView instanceof LauncherAppWidgetHostView) { + // App widgets are technically scaled, but are drawn at their expected size -- so the + // app widget scale should not affect the scale of the preview. + scale /= ((LauncherAppWidgetHostView) mView).getScaleToFit(); + } + + outPos[0] = Math.round(outPos[0] + - (view.getWidth() - scale * mView.getWidth() * mView.getScaleX()) / 2); + outPos[1] = Math.round(outPos[1] - (1 - scale) * view.getHeight() / 2 - previewPadding / 2); + return scale; + } + protected Bitmap convertPreviewToAlphaBitmap(Bitmap preview) { return preview.copy(Bitmap.Config.ALPHA_8, true); } diff --git a/src/com/android/launcher3/widget/PendingItemDragHelper.java b/src/com/android/launcher3/widget/PendingItemDragHelper.java index e78d517b09..df368cd3e5 100644 --- a/src/com/android/launcher3/widget/PendingItemDragHelper.java +++ b/src/com/android/launcher3/widget/PendingItemDragHelper.java @@ -33,7 +33,6 @@ import com.android.launcher3.Launcher; import com.android.launcher3.LauncherAppState; import com.android.launcher3.PendingAddItemInfo; import com.android.launcher3.R; -import com.android.launcher3.dragndrop.AppWidgetHostViewDrawable; import com.android.launcher3.dragndrop.DragOptions; import com.android.launcher3.dragndrop.DraggableView; import com.android.launcher3.graphics.DragPreviewProvider; @@ -93,6 +92,8 @@ public class PendingItemDragHelper extends DragPreviewProvider { LauncherAppState app = LauncherAppState.getInstance(launcher); Drawable preview = null; + final int previewWidth; + final int previewHeight; final float scale; final Point dragOffset; final Rect dragRegion; @@ -114,12 +115,11 @@ public class PendingItemDragHelper extends DragPreviewProvider { createWidgetInfo.info, maxWidth, previewSizeBeforeScale)); } if (mAppWidgetHostViewPreview != null) { - preview = new AppWidgetHostViewDrawable(mAppWidgetHostViewPreview); previewSizeBeforeScale[0] = mAppWidgetHostViewPreview.getMeasuredWidth(); launcher.getDragController() .addDragListener(new AppWidgetHostViewDragListener(launcher)); } - if (preview == null) { + if (preview == null && mAppWidgetHostViewPreview == null) { Drawable p = new FastBitmapDrawable( app.getWidgetCache().generateWidgetPreview(launcher, createWidgetInfo.info, maxWidth, null, @@ -140,7 +140,14 @@ public class PendingItemDragHelper extends DragPreviewProvider { previewBounds.left += padding; previewBounds.right -= padding; } - scale = previewBounds.width() / (float) preview.getIntrinsicWidth(); + if (mAppWidgetHostViewPreview != null) { + previewWidth = mAppWidgetHostViewPreview.getMeasuredWidth(); + previewHeight = mAppWidgetHostViewPreview.getMeasuredHeight(); + } else { + previewWidth = preview.getIntrinsicWidth(); + previewHeight = preview.getIntrinsicHeight(); + } + scale = previewBounds.width() / (float) previewWidth; launcher.getDragController().addDragListener(new WidgetHostViewLoader(launcher, mView)); dragOffset = null; @@ -152,8 +159,10 @@ public class PendingItemDragHelper extends DragPreviewProvider { LauncherIcons li = LauncherIcons.obtain(launcher); preview = new FastBitmapDrawable( li.createScaledBitmapWithoutShadow(icon, 0)); + previewWidth = preview.getIntrinsicWidth(); + previewHeight = preview.getIntrinsicHeight(); li.recycle(); - scale = ((float) launcher.getDeviceProfile().iconSizePx) / preview.getIntrinsicWidth(); + scale = ((float) launcher.getDeviceProfile().iconSizePx) / previewWidth; dragOffset = new Point(previewPadding / 2, previewPadding / 2); @@ -181,13 +190,19 @@ public class PendingItemDragHelper extends DragPreviewProvider { launcher.getWorkspace().prepareDragWithProvider(this); int dragLayerX = screenPos.x + previewBounds.left - + (int) ((scale * preview.getIntrinsicWidth() - preview.getIntrinsicWidth()) / 2); + + (int) ((scale * previewWidth - previewWidth) / 2); int dragLayerY = screenPos.y + previewBounds.top - + (int) ((scale * preview.getIntrinsicHeight() - preview.getIntrinsicHeight()) / 2); + + (int) ((scale * previewHeight - previewHeight) / 2); // Start the drag - launcher.getDragController().startDrag(preview, draggableView, dragLayerX, dragLayerY, - source, mAddInfo, dragOffset, dragRegion, scale, scale, options); + if (mAppWidgetHostViewPreview != null) { + launcher.getDragController().startDrag(mAppWidgetHostViewPreview, draggableView, + dragLayerX, dragLayerY, source, mAddInfo, dragOffset, dragRegion, scale, scale, + options); + } else { + launcher.getDragController().startDrag(preview, draggableView, dragLayerX, dragLayerY, + source, mAddInfo, dragOffset, dragRegion, scale, scale, options); + } } @Override diff --git a/src/com/android/launcher3/widget/dragndrop/AppWidgetHostViewDragListener.java b/src/com/android/launcher3/widget/dragndrop/AppWidgetHostViewDragListener.java index 66bb363dde..4a60983624 100644 --- a/src/com/android/launcher3/widget/dragndrop/AppWidgetHostViewDragListener.java +++ b/src/com/android/launcher3/widget/dragndrop/AppWidgetHostViewDragListener.java @@ -17,7 +17,6 @@ package com.android.launcher3.widget.dragndrop; import com.android.launcher3.DropTarget; import com.android.launcher3.Launcher; -import com.android.launcher3.dragndrop.AppWidgetHostViewDrawable; import com.android.launcher3.dragndrop.DragController; import com.android.launcher3.dragndrop.DragOptions; import com.android.launcher3.widget.LauncherAppWidgetHostView; @@ -26,7 +25,6 @@ import com.android.launcher3.widget.LauncherAppWidgetHostView; public final class AppWidgetHostViewDragListener implements DragController.DragListener { private final Launcher mLauncher; private DropTarget.DragObject mDragObject; - private AppWidgetHostViewDrawable mAppWidgetHostViewDrawable; private LauncherAppWidgetHostView mAppWidgetHostView; public AppWidgetHostViewDragListener(Launcher launcher) { @@ -35,11 +33,9 @@ public final class AppWidgetHostViewDragListener implements DragController.DragL @Override public void onDragStart(DropTarget.DragObject dragObject, DragOptions unused) { - if (dragObject.dragView.getDrawable() instanceof AppWidgetHostViewDrawable) { + if (dragObject.dragView.getContentView() instanceof LauncherAppWidgetHostView) { mDragObject = dragObject; - mAppWidgetHostViewDrawable = - (AppWidgetHostViewDrawable) mDragObject.dragView.getDrawable(); - mAppWidgetHostView = mAppWidgetHostViewDrawable.getAppWidgetHostView(); + mAppWidgetHostView = (LauncherAppWidgetHostView) dragObject.dragView.getContentView(); mAppWidgetHostView.startDrag(this); } else { mLauncher.getDragController().removeDragListener(this);