Android Problems Converting ViewGroup with Children into Bitmap

眉间皱痕 提交于 2019-11-28 20:35:32

问题


I'm successfully converting a ViewGroup (RelativeLayout) into Bitmap using a Canvas. However, when the draw happens I only see the ViewGroup with its background drawable and not its children (two TextViews) who should be laid out within the RelativeLayout using rules like FILL_PARENT.

The RelativeLayout is created using the following static function:

public static RelativeLayout createProgrammeView(Context context, int width, int height, String title, String time) {
    RelativeLayout.LayoutParams params;

    // Layout Root View (RelativeLayout)
    RelativeLayout rlv = new RelativeLayout(context);
    params = new RelativeLayout.LayoutParams(width, height);
    rlv.setLayoutParams(params);
    rlv.setPadding(3, 3, 3, 3);
    rlv.setBackgroundResource(R.drawable.background);

    // Layout Title
    TextView tv = new TextView(context);
    params = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.FILL_PARENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
    params.addRule(RelativeLayout.ALIGN_PARENT_TOP);
    params.addRule(RelativeLayout.ALIGN_PARENT_LEFT);
    params.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
    tv.setId(R.id.title);
    tv.setLayoutParams(params);
    tv.setGravity(Gravity.CENTER_VERTICAL);
    tv.setSingleLine(true);
    tv.setEllipsize(TruncateAt.END);
    tv.setTextColor(Color.parseColor("#fff"));
    tv.setTextSize(11);
    tv.setText(title);
    rlv.addView(tv);

    // Layout Start Time
    tv = new TextView(context);
    params = new RelativeLayout.LayoutParams(16, RelativeLayout.LayoutParams.WRAP_CONTENT);
    params.addRule(RelativeLayout.BELOW, R.id.title);
    params.addRule(RelativeLayout.ALIGN_PARENT_LEFT);
    params.setMargins(0, 4, 0, 0);
    tv.setId(R.id.time);
    tv.setLayoutParams(params);
    tv.setGravity(Gravity.CENTER_VERTICAL);
    tv.setSingleLine(true);
    tv.setEllipsize(null);
    tv.setTextColor(Color.parseColor("#fff"));
    tv.setTextSize(10);
    tv.setText(time);
    rlv.addView(tv);
    }

    return rlv;
}

I then use the following to turn the RelativeLayout into a Bitmap:

public static Bitmap loadBitmapFromView(RelativeLayout v) {
    Bitmap b = Bitmap.createBitmap(v.getLayoutParams().width, v.getLayoutParams().height, Bitmap.Config.RGB_565);
    Canvas c = new Canvas(b);
    v.draw(c);
    return b;
}

As expected this gives me a nice Bitmap in the dimensions that I require with the background drawable, but the children are not in the bitmap. I call these functions quite a lot to build a large image which then gets drawn onto a custom view in my activity.

This is the loop which calls the static function:

public static void renderViews(final Context context) {
    largeBitmap = Bitmap.createBitmap(largeWidth, largeHeight, Bitmap.Config.RGB_565);
    Canvas largeCanvas = new Canvas(largeBitmap);

    for (int i = 0; i < items.size(); i++) {
        int leftMargin = ...SOME CALCULATIONS...;

        RelativeLayout newView = createProgrammeView(context, width, rowHeight, "Title", "21:00");
        Bitmap newViewBitmap = loadBitmapFromView(newView);

        largeCanvas.drawBitmap(newViewBitmap, leftMargin, 0, new Paint());
    }

    myCustomView.invalidate();
}

My custom view overrides the onDraw() function:

@Override
protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    canvas.drawBitmap(largeBitmap, 0, 0, null);
}

From what I can see I believe this is because Android doesn't call a measure() on the child Views. I have tried calling this manually, but this doesn't solve the problem.

So, I guess what I would like to know is, how can I achieve converting a RelativeLayout with children into a Bitmap and get Android to measure the children so they respect their relative layout rules.

Many thanks to anyone who can help me work this out.

Rob


回答1:


The problem is that you did not measure and layout the container. You must call v.measure(widthSpec, heightSpec) and then v.layout(left, top, right, bottom) before drawing can work. The first method will make sure the view knows how big you want it to be, and the second method will ensure the children are positioned properly.

In your case you would do:

v.measure(MeasureSpec.makeMeasureSpec(v.getLayoutParams().width, MeasureSpec.EXACTLY),
        MeasureSpec.makeMeasureSpec(v.getLayoutParams().height, MeasureSpec.EXACTLY));
v.layout(0, 0, v.getMeasuredWidth(), v.getMeasuredHeight());

Bitmap b = Bitmap.createBitmap(v.getWidth(), v.getHeight(), Bitmap.Config.RGB_565);
Canvas c = new Canvas(b);
v.draw(c);



回答2:


Solution that based on DisplayMetrics for the Layouts could be useful as well. In order not to repeat - look here .



来源:https://stackoverflow.com/questions/4960753/android-problems-converting-viewgroup-with-children-into-bitmap

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!