Android 将带有子项的 ViewGroup 转换为位图时出现问题

标签 android android-layout bitmap android-relativelayout

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

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

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 转换为位图:

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

正如预期的那样,这为我提供了背景可绘制对象所需尺寸的漂亮位图,但子项不在位图中。我经常调用这些函数来构建一个大图像,然后将其绘制到我的 Activity 中的自定义 View 上。

这是调用静态函数的循环:

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

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

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

据我所知,我相信这是因为 Android 没有在 subview 上调用 measure()。我试过手动调用它,但这并没有解决问题。

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

非常感谢任何能帮我解决这个问题的人。

罗布

最佳答案

问题是您没有测量和布局容器。您必须调用v.measure(widthSpec, heightSpec),然后调用v.layout( left, top, right, bottom) 在绘图可以工作之前。第一种方法将确保 View 知道您希望它有多大,第二种方法将确保子项的位置正确。

在你的情况下你会这样做:

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 转换为位图时出现问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4960753/

相关文章:

android - 如何使用 OpenGL 在 Android 上绘制位图

c++ - 将位图旋转 90 度

java - Android - 可打包 | putParcelableArrayListExtra ("ListItems", listItems);

android - ActionBar 兼容性和透明度

java - Android 水平轮(自定义)DatePicker 中的问题

android - 如何将 ViewPager 的高度包装到其当前 Fragment 的高度?

Android:为什么相同权重的按钮具有不同的宽度?

java - onClick 继续停止

java - 如何将 EditText 中的值添加到自定义 ListView?

java - 使用glide加载位图到ImageView