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