Android 将带有子项的 ViewGroup 转换为位图的问题 [英] Android Problems Converting ViewGroup with Children into Bitmap

查看:21
本文介绍了Android 将带有子项的 ViewGroup 转换为位图的问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用 Canvas 成功地将 ViewGroup (RelativeLayout) 转换为 Bitmap.但是,当绘制发生时,我只看到 ViewGroup 及其背景可绘制,而不是它的子项(两个 TextViews),它们应该使用 FILL_PARENT 之类的规则布置在 RelativeLayout 中.

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.

RelativeLayout 是使用以下静态函数创建的:

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;
}

然后我使用以下内容将 RelativeLayout 转换为位图:

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();
}

我的自定义视图覆盖了 onDraw() 函数:

My custom view overrides the onDraw() function:

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

据我所知,我相信这是因为 Android 不会在子视图上调用 measure().我试过手动调用它,但这并不能解决问题.

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.

所以,我想我想知道的是,我怎样才能实现将带有子项的 RelativeLayout 转换为位图并让 Android 测量子项,以便他们尊重他们的相对布局规则.

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.

罗布

推荐答案

问题在于你没有对容器进行测量和布局. 你必须调用 v.measure(widthSpec, heightSpec) 然后 v.layout(left, top, right, bottom) 才可以绘图.第一种方法将确保视图知道您希望它有多大,第二种方法将确保子项正确定位.

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);

这篇关于Android 将带有子项的 ViewGroup 转换为位图的问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆