1 package com.android.launcher3.dragndrop; 2 3 import android.content.Context; 4 import android.graphics.Bitmap; 5 import android.graphics.Canvas; 6 import android.util.AttributeSet; 7 import android.view.View; 8 import android.widget.FrameLayout; 9 import android.widget.RemoteViews; 10 11 import com.android.launcher3.BaseActivity; 12 import com.android.launcher3.DeviceProfile; 13 import com.android.launcher3.LauncherAppWidgetProviderInfo; 14 import com.android.launcher3.widget.WidgetCell; 15 16 /** 17 * Extension of {@link WidgetCell} which supports generating previews from {@link RemoteViews} 18 */ 19 public class LivePreviewWidgetCell extends WidgetCell { 20 21 private RemoteViews mPreview; 22 LivePreviewWidgetCell(Context context)23 public LivePreviewWidgetCell(Context context) { 24 this(context, null); 25 } 26 LivePreviewWidgetCell(Context context, AttributeSet attrs)27 public LivePreviewWidgetCell(Context context, AttributeSet attrs) { 28 this(context, attrs, 0); 29 } 30 LivePreviewWidgetCell(Context context, AttributeSet attrs, int defStyle)31 public LivePreviewWidgetCell(Context context, AttributeSet attrs, int defStyle) { 32 super(context, attrs, defStyle); 33 } 34 setPreview(RemoteViews view)35 public void setPreview(RemoteViews view) { 36 mPreview = view; 37 } 38 39 @Override ensurePreview()40 public void ensurePreview() { 41 if (mPreview != null && mActiveRequest == null) { 42 Bitmap preview = generateFromRemoteViews( 43 mActivity, mPreview, mItem.widgetInfo, mPresetPreviewSize, new int[1]); 44 if (preview != null) { 45 applyPreview(preview); 46 return; 47 } 48 } 49 super.ensurePreview(); 50 } 51 52 /** 53 * Generates a bitmap by inflating {@param views}. 54 * @see com.android.launcher3.WidgetPreviewLoader#generateWidgetPreview 55 * 56 * TODO: Consider moving this to the background thread. 57 */ generateFromRemoteViews(BaseActivity activity, RemoteViews views, LauncherAppWidgetProviderInfo info, int previewSize, int[] preScaledWidthOut)58 public static Bitmap generateFromRemoteViews(BaseActivity activity, RemoteViews views, 59 LauncherAppWidgetProviderInfo info, int previewSize, int[] preScaledWidthOut) { 60 61 DeviceProfile dp = activity.getDeviceProfile(); 62 int viewWidth = dp.cellWidthPx * info.spanX; 63 int viewHeight = dp.cellHeightPx * info.spanY; 64 65 final View v; 66 try { 67 v = views.apply(activity, new FrameLayout(activity)); 68 v.measure(MeasureSpec.makeMeasureSpec(viewWidth, MeasureSpec.EXACTLY), 69 MeasureSpec.makeMeasureSpec(viewHeight, MeasureSpec.EXACTLY)); 70 71 viewWidth = v.getMeasuredWidth(); 72 viewHeight = v.getMeasuredHeight(); 73 v.layout(0, 0, viewWidth, viewHeight); 74 } catch (Exception e) { 75 return null; 76 } 77 78 preScaledWidthOut[0] = viewWidth; 79 final int bitmapWidth, bitmapHeight; 80 final float scale; 81 if (viewWidth > previewSize) { 82 scale = ((float) previewSize) / viewWidth; 83 bitmapWidth = previewSize; 84 bitmapHeight = (int) (viewHeight * scale); 85 } else { 86 scale = 1; 87 bitmapWidth = viewWidth; 88 bitmapHeight = viewHeight; 89 } 90 91 Bitmap preview = Bitmap.createBitmap(bitmapWidth, bitmapHeight, Bitmap.Config.ARGB_8888); 92 Canvas c = new Canvas(preview); 93 c.scale(scale, scale); 94 v.draw(c); 95 c.setBitmap(null); 96 return preview; 97 } 98 } 99