Merge "Render RemoteViews in LauncherAppWidgetHostView" into sc-dev
This commit is contained in:
commit
6f944f3624
|
@ -59,6 +59,7 @@ import com.android.launcher3.pm.PinRequestHelper;
|
|||
import com.android.launcher3.views.BaseDragLayer;
|
||||
import com.android.launcher3.widget.LauncherAppWidgetHost;
|
||||
import com.android.launcher3.widget.LauncherAppWidgetProviderInfo;
|
||||
import com.android.launcher3.widget.NavigableAppWidgetHostView;
|
||||
import com.android.launcher3.widget.PendingAddShortcutInfo;
|
||||
import com.android.launcher3.widget.PendingAddWidgetInfo;
|
||||
import com.android.launcher3.widget.WidgetCell;
|
||||
|
@ -147,20 +148,31 @@ public class AddItemActivity extends BaseActivity implements OnLongClickListener
|
|||
public boolean onLongClick(View view) {
|
||||
// Find the position of the preview relative to the touch location.
|
||||
WidgetImageView img = mWidgetCell.getWidgetView();
|
||||
NavigableAppWidgetHostView appWidgetHostView = mWidgetCell.getAppWidgetHostViewPreview();
|
||||
|
||||
// If the ImageView doesn't have a drawable yet, the widget preview hasn't been loaded and
|
||||
// we abort the drag.
|
||||
if (img.getDrawable() == null) {
|
||||
if (img.getDrawable() == null && appWidgetHostView == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Rect bounds = img.getBitmapBounds();
|
||||
bounds.offset(img.getLeft() - (int) mLastTouchPos.x, img.getTop() - (int) mLastTouchPos.y);
|
||||
|
||||
final Rect bounds;
|
||||
// Start home and pass the draw request params
|
||||
PinItemDragListener listener = new PinItemDragListener(mRequest, bounds,
|
||||
img.getDrawable().getIntrinsicWidth(), img.getWidth());
|
||||
|
||||
final PinItemDragListener listener;
|
||||
if (appWidgetHostView != null) {
|
||||
bounds = new Rect();
|
||||
appWidgetHostView.getSourceVisualDragBounds(bounds);
|
||||
bounds.offset(appWidgetHostView.getLeft() - (int) mLastTouchPos.x,
|
||||
appWidgetHostView.getTop() - (int) mLastTouchPos.y);
|
||||
listener = new PinItemDragListener(mRequest, bounds,
|
||||
appWidgetHostView.getMeasuredWidth(), appWidgetHostView.getMeasuredWidth());
|
||||
} else {
|
||||
bounds = img.getBitmapBounds();
|
||||
bounds.offset(img.getLeft() - (int) mLastTouchPos.x,
|
||||
img.getTop() - (int) mLastTouchPos.y);
|
||||
listener = new PinItemDragListener(mRequest, bounds,
|
||||
img.getDrawable().getIntrinsicWidth(), img.getWidth());
|
||||
}
|
||||
|
||||
// Start a system drag and drop. We use a transparent bitmap as preview for system drag
|
||||
// as the preview is handled internally by launcher.
|
||||
|
@ -214,7 +226,7 @@ public class AddItemActivity extends BaseActivity implements OnLongClickListener
|
|||
// Cannot add widget
|
||||
return false;
|
||||
}
|
||||
mWidgetCell.setPreview(PinItemDragListener.getPreview(mRequest));
|
||||
mWidgetCell.setRemoteViewsPreview(PinItemDragListener.getPreview(mRequest));
|
||||
|
||||
mAppWidgetManager = new WidgetManagerHelper(this);
|
||||
mAppWidgetHost = new LauncherAppWidgetHost(this);
|
||||
|
@ -238,6 +250,7 @@ public class AddItemActivity extends BaseActivity implements OnLongClickListener
|
|||
|
||||
@Override
|
||||
protected void onPostExecute(WidgetItem item) {
|
||||
mWidgetCell.setPreviewSize(item.spanX, item.spanY);
|
||||
mWidgetCell.applyFromCellItem(item, mApp.getWidgetCache());
|
||||
mWidgetCell.ensurePreview();
|
||||
}
|
||||
|
|
|
@ -114,7 +114,7 @@ public abstract class BaseWidgetSheet extends AbstractSlideInView
|
|||
}
|
||||
|
||||
PendingItemDragHelper dragHelper = new PendingItemDragHelper(v);
|
||||
dragHelper.setRemoteViewsPreview(v.getPreview());
|
||||
dragHelper.setRemoteViewsPreview(v.getRemoteViewsPreview());
|
||||
dragHelper.setAppWidgetHostViewPreview(v.getAppWidgetHostViewPreview());
|
||||
|
||||
if (image.getDrawable() != null) {
|
||||
|
|
|
@ -23,6 +23,7 @@ import android.graphics.Point;
|
|||
import android.graphics.Rect;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.view.View;
|
||||
import android.view.View.MeasureSpec;
|
||||
import android.widget.RemoteViews;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
@ -53,7 +54,7 @@ public class PendingItemDragHelper extends DragPreviewProvider {
|
|||
private int[] mEstimatedCellSize;
|
||||
|
||||
@Nullable private RemoteViews mRemoteViewsPreview;
|
||||
@Nullable private LauncherAppWidgetHostView mAppWidgetHostViewPreview;
|
||||
@Nullable private NavigableAppWidgetHostView mAppWidgetHostViewPreview;
|
||||
private final float mEnforcedRoundedCornersForWidget;
|
||||
|
||||
public PendingItemDragHelper(View view) {
|
||||
|
@ -71,9 +72,9 @@ public class PendingItemDragHelper extends DragPreviewProvider {
|
|||
mRemoteViewsPreview = remoteViewsPreview;
|
||||
}
|
||||
|
||||
/** Sets a {@link LauncherAppWidgetHostView} which shows a preview layout of an app widget. */
|
||||
/** Sets a {@link NavigableAppWidgetHostView} which shows a preview layout of an app widget. */
|
||||
public void setAppWidgetHostViewPreview(
|
||||
@Nullable LauncherAppWidgetHostView appWidgetHostViewPreview) {
|
||||
@Nullable NavigableAppWidgetHostView appWidgetHostViewPreview) {
|
||||
mAppWidgetHostViewPreview = appWidgetHostViewPreview;
|
||||
}
|
||||
|
||||
|
@ -110,9 +111,22 @@ public class PendingItemDragHelper extends DragPreviewProvider {
|
|||
int[] previewSizeBeforeScale = new int[1];
|
||||
|
||||
if (mRemoteViewsPreview != null) {
|
||||
preview = new FastBitmapDrawable(
|
||||
WidgetCell.generateFromRemoteViews(launcher, mRemoteViewsPreview,
|
||||
createWidgetInfo.info, maxWidth, previewSizeBeforeScale));
|
||||
mAppWidgetHostViewPreview = new LauncherAppWidgetHostView(launcher);
|
||||
mAppWidgetHostViewPreview.setAppWidget(/* appWidgetId= */ -1,
|
||||
((PendingAddWidgetInfo) mAddInfo).info);
|
||||
DeviceProfile deviceProfile = launcher.getDeviceProfile();
|
||||
Rect padding = new Rect();
|
||||
mAppWidgetHostViewPreview.getWidgetInset(deviceProfile, padding);
|
||||
mAppWidgetHostViewPreview.setPadding(padding.left, padding.top, padding.right,
|
||||
padding.bottom);
|
||||
mAppWidgetHostViewPreview.updateAppWidget(/* remoteViews= */ mRemoteViewsPreview);
|
||||
int width =
|
||||
deviceProfile.cellWidthPx * mAddInfo.spanX + padding.left + padding.right;
|
||||
int height =
|
||||
deviceProfile.cellHeightPx * mAddInfo.spanY + padding.top + padding.bottom;
|
||||
mAppWidgetHostViewPreview.measure(
|
||||
MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY),
|
||||
MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY));
|
||||
}
|
||||
if (mAppWidgetHostViewPreview != null) {
|
||||
previewSizeBeforeScale[0] = mAppWidgetHostViewPreview.getMeasuredWidth();
|
||||
|
|
|
@ -46,7 +46,6 @@ import com.android.launcher3.DeviceProfile;
|
|||
import com.android.launcher3.R;
|
||||
import com.android.launcher3.WidgetPreviewLoader;
|
||||
import com.android.launcher3.icons.BaseIconFactory;
|
||||
import com.android.launcher3.icons.BitmapRenderer;
|
||||
import com.android.launcher3.icons.FastBitmapDrawable;
|
||||
import com.android.launcher3.icons.RoundDrawableWrapper;
|
||||
import com.android.launcher3.model.WidgetItem;
|
||||
|
@ -100,8 +99,8 @@ public class WidgetCell extends LinearLayout implements OnLayoutChangeListener {
|
|||
private final CheckLongPressHelper mLongPressHelper;
|
||||
private final float mEnforcedCornerRadius;
|
||||
|
||||
private RemoteViews mPreview;
|
||||
private LauncherAppWidgetHostView mAppWidgetHostViewPreview;
|
||||
private RemoteViews mRemoteViewsPreview;
|
||||
private NavigableAppWidgetHostView mAppWidgetHostViewPreview;
|
||||
|
||||
public WidgetCell(Context context) {
|
||||
this(context, null);
|
||||
|
@ -143,12 +142,13 @@ public class WidgetCell extends LinearLayout implements OnLayoutChangeListener {
|
|||
mWidgetDescription = findViewById(R.id.widget_description);
|
||||
}
|
||||
|
||||
public void setPreview(RemoteViews view) {
|
||||
mPreview = view;
|
||||
public void setRemoteViewsPreview(RemoteViews view) {
|
||||
mRemoteViewsPreview = view;
|
||||
}
|
||||
|
||||
public RemoteViews getPreview() {
|
||||
return mPreview;
|
||||
@Nullable
|
||||
public RemoteViews getRemoteViewsPreview() {
|
||||
return mRemoteViewsPreview;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -172,7 +172,7 @@ public class WidgetCell extends LinearLayout implements OnLayoutChangeListener {
|
|||
mActiveRequest.cancel();
|
||||
mActiveRequest = null;
|
||||
}
|
||||
mPreview = null;
|
||||
mRemoteViewsPreview = null;
|
||||
if (mAppWidgetHostViewPreview != null) {
|
||||
mWidgetImageContainer.removeView(mAppWidgetHostViewPreview);
|
||||
}
|
||||
|
@ -180,7 +180,7 @@ public class WidgetCell extends LinearLayout implements OnLayoutChangeListener {
|
|||
}
|
||||
|
||||
public void applyFromCellItem(WidgetItem item, WidgetPreviewLoader loader) {
|
||||
applyPreviewLayout(item);
|
||||
applyPreviewOnAppWidgetHostView(item);
|
||||
|
||||
mItem = item;
|
||||
mWidgetName.setText(mItem.label);
|
||||
|
@ -206,9 +206,26 @@ public class WidgetCell extends LinearLayout implements OnLayoutChangeListener {
|
|||
}
|
||||
}
|
||||
|
||||
private void applyPreviewLayout(WidgetItem item) {
|
||||
|
||||
private void applyPreviewOnAppWidgetHostView(WidgetItem item) {
|
||||
if (mRemoteViewsPreview != null) {
|
||||
mAppWidgetHostViewPreview = new NavigableAppWidgetHostView(getContext()) {
|
||||
@Override
|
||||
protected boolean shouldAllowDirectClick() {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
mAppWidgetHostViewPreview.setAppWidget(/* appWidgetId= */ -1, item.widgetInfo);
|
||||
Rect padding = new Rect();
|
||||
mAppWidgetHostViewPreview.getWidgetInset(mActivity.getDeviceProfile(), padding);
|
||||
mAppWidgetHostViewPreview.setPadding(padding.left, padding.top, padding.right,
|
||||
padding.bottom);
|
||||
mAppWidgetHostViewPreview.updateAppWidget(/* remoteViews= */ mRemoteViewsPreview);
|
||||
return;
|
||||
}
|
||||
|
||||
if (ATLEAST_S
|
||||
&& mPreview == null
|
||||
&& mRemoteViewsPreview == null
|
||||
&& item.widgetInfo != null
|
||||
&& item.widgetInfo.previewLayout != Resources.ID_NULL) {
|
||||
mAppWidgetHostViewPreview = new LauncherAppWidgetHostView(getContext());
|
||||
|
@ -234,7 +251,7 @@ public class WidgetCell extends LinearLayout implements OnLayoutChangeListener {
|
|||
}
|
||||
|
||||
@Nullable
|
||||
public LauncherAppWidgetHostView getAppWidgetHostViewPreview() {
|
||||
public NavigableAppWidgetHostView getAppWidgetHostViewPreview() {
|
||||
return mAppWidgetHostViewPreview;
|
||||
}
|
||||
|
||||
|
@ -303,15 +320,6 @@ public class WidgetCell extends LinearLayout implements OnLayoutChangeListener {
|
|||
}
|
||||
|
||||
public void ensurePreview() {
|
||||
if (mPreview != null && mActiveRequest == null) {
|
||||
Bitmap preview = generateFromRemoteViews(
|
||||
mActivity, mPreview, mItem.widgetInfo, mPresetPreviewSize, new int[1]);
|
||||
if (preview != null) {
|
||||
applyPreview(new FastBitmapDrawable(preview));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (mAppWidgetHostViewPreview != null) {
|
||||
setContainerSize(mPreviewWidth, mPreviewHeight);
|
||||
FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(
|
||||
|
@ -385,53 +393,4 @@ public class WidgetCell extends LinearLayout implements OnLayoutChangeListener {
|
|||
super.onInitializeAccessibilityNodeInfo(info);
|
||||
info.removeAction(AccessibilityNodeInfo.AccessibilityAction.ACTION_CLICK);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a bitmap by inflating {@param views}.
|
||||
* @see com.android.launcher3.WidgetPreviewLoader#generateWidgetPreview
|
||||
*
|
||||
* TODO: Consider moving this to the background thread.
|
||||
*/
|
||||
public static Bitmap generateFromRemoteViews(BaseActivity activity, RemoteViews views,
|
||||
LauncherAppWidgetProviderInfo info, int previewSize, int[] preScaledWidthOut) {
|
||||
try {
|
||||
return generateFromView(activity, views.apply(activity, new FrameLayout(activity)),
|
||||
info, previewSize, preScaledWidthOut);
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private static Bitmap generateFromView(BaseActivity activity, View v,
|
||||
LauncherAppWidgetProviderInfo info, int previewSize, int[] preScaledWidthOut) {
|
||||
|
||||
DeviceProfile dp = activity.getDeviceProfile();
|
||||
int viewWidth = dp.cellWidthPx * info.spanX;
|
||||
int viewHeight = dp.cellHeightPx * info.spanY;
|
||||
|
||||
v.measure(MeasureSpec.makeMeasureSpec(viewWidth, MeasureSpec.EXACTLY),
|
||||
MeasureSpec.makeMeasureSpec(viewHeight, MeasureSpec.EXACTLY));
|
||||
|
||||
viewWidth = v.getMeasuredWidth();
|
||||
viewHeight = v.getMeasuredHeight();
|
||||
v.layout(0, 0, viewWidth, viewHeight);
|
||||
|
||||
preScaledWidthOut[0] = viewWidth;
|
||||
final int bitmapWidth, bitmapHeight;
|
||||
final float scale;
|
||||
if (viewWidth > previewSize) {
|
||||
scale = ((float) previewSize) / viewWidth;
|
||||
bitmapWidth = previewSize;
|
||||
bitmapHeight = (int) (viewHeight * scale);
|
||||
} else {
|
||||
scale = 1;
|
||||
bitmapWidth = viewWidth;
|
||||
bitmapHeight = viewHeight;
|
||||
}
|
||||
|
||||
return BitmapRenderer.createSoftwareBitmap(bitmapWidth, bitmapHeight, c -> {
|
||||
c.scale(scale, scale);
|
||||
v.draw(c);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue