I have a layout resource like this and a I want to inflate it with the layout width and height:
One option is to define constants for layout_width
and layout_height
in the form of attributes and access them programatically in getBitmap
.
This example should work. Might take some tweaking to get it perfect, depending on your needs, but give it a shot:
//Get a bitmap from a layout resource. Inflates it into a discarded LinearLayout
//so that the LayoutParams are preserved
public static Bitmap getLayoutBitmap (Context c, int layoutRes, int maxWidth, int maxHeight) {
View view = LayoutInflater.from(c).inflate(layoutRes, new LinearLayout(c), false);
return getViewBitmap(view, maxWidth, maxHeight);
}
public static Bitmap getViewBitmap (View v, int maxWidth, int maxHeight) {
ViewGroup.LayoutParams vParams = v.getLayoutParams();
//If the View hasn't been attached to a layout, or had LayoutParams set
//return null, or handle this case however you want
if (vParams == null) {
return null;
}
int wSpec = measureSpecFromDimension(vParams.width, maxWidth);
int hSpec = measureSpecFromDimension(vParams.height, maxHeight);
v.measure(wSpec, hSpec);
final int width = v.getMeasuredWidth();
final int height = v.getMeasuredHeight();
//Cannot make a zero-width or zero-height bitmap
if (width == 0 || height == 0) {
return null;
}
v.layout(0, 0, width, height);
Bitmap result = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(result);
v.draw(canvas);
return result;
}
private static int measureSpecFromDimension (int dimension, int maxDimension) {
switch (dimension) {
case ViewGroup.LayoutParams.MATCH_PARENT:
return View.MeasureSpec.makeMeasureSpec(maxDimension, View.MeasureSpec.EXACTLY);
case ViewGroup.LayoutParams.WRAP_CONTENT:
return View.MeasureSpec.makeMeasureSpec(maxDimension, View.MeasureSpec.AT_MOST);
default:
return View.MeasureSpec.makeMeasureSpec(dimension, View.MeasureSpec.EXACTLY);
}
}