Programmatically Inflate View with pre-defined measures
Asked Answered
D

2

1

I have a layout resource like this and a I want to inflate it with the layout width and height:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="75px"
    android:layout_height="25px">

    <TextView
        android:id="@+id/drawable_name"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        android:layout_centerHorizontal="true"
        android:text="Name" />

    <TextView
        android:id="@+id/drawable_description"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignLeft="@id/drawable_name"
        android:layout_alignParentLeft="true"
        android:gravity="center_horizontal"
        android:layout_below="@+id/drawable_name"
        android:text="Some Text" />

</RelativeLayout>

The View could be anything, and I'm converting it to Bitmap.

private Bitmap getBitmap(View v){
    v.measure(MeasureSpec.makeMeasureSpec(mDrawableWidth, MeasureSpec.EXACTLY),
              MeasureSpec.makeMeasureSpec(mDrawableHeight, MeasureSpec.EXACTLY));
    v.layout(0, 0, mDrawableWidth, mDrawableHeight);
    Bitmap returnedBitmap = Bitmap.createBitmap(mDrawableWidth, mDrawableHeight,Bitmap.Config.ARGB_8888);
    Canvas c=new Canvas(returnedBitmap);
    v.draw(c);
    return returnedBitmap;
}

Until now, I have the Width and Height hardcoded and I want to be able to do it programatically, accessing the layout_width and layout_height. Is there any way to achieve this? If there's another way of inflating the view with this values without specifying them in the measure, please let me know.

If I create a Custom View, is there any chance of specifying the fixed width and height?

Diverticulosis answered 2/9, 2013 at 3:16 Comment(0)
T
1

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);
    }
}
Thulium answered 2/9, 2013 at 3:57 Comment(5)
Thanks for the quick answer but the LayoutParameter from the View is null at that point. and the view will not be attached to a parent. I just want to create a Bitmap from that Layout.Diverticulosis
If I create a Custom View, is there any chance of specifying the fixed width and height?Diverticulosis
If the LayoutParams are null, that means it wasn't inflated to a container. How are you inflating the View?Thulium
See the edited comment above. I don't want to attach it to a container, I just want the bitmap of the view. And yes the view is inflated with this mInflater.inflate(mLayout, null, false);Diverticulosis
It has to be inflated into a container (not necessarily attached, but inflated into it so that the LayoutParams are not discarded). I've attached an example.Thulium
H
0

One option is to define constants for layout_width and layout_height in the form of attributes and access them programatically in getBitmap.

Hinds answered 2/9, 2013 at 3:51 Comment(2)
Yes, I've remembered it but it's not an option. Thanks for the quick answer.Diverticulosis
If I create a Custom View, is there any chance of specifying the fixed width and height?Diverticulosis

© 2022 - 2024 — McMap. All rights reserved.