Android 离屏视图仅绘制其背景,不绘制任何其他内容

Android offscreen view draws only its background and nothing else

我正在尝试创建和渲染一个完全离屏的视图。首先,我尝试过(来自 http://arpitonline.com/2012/07/17/capturing-bitmaps-of-views-in-android/):

Bitmap result = Bitmap.createBitmap(1080, 1080, Bitmap.Config.ARGB_8888);
Canvas c = new Canvas(result);
view.layout(0, 0, 1080, 1080);
view.draw(c);
return result;

它只渲染了我视图的背景颜色。它的大小和背景颜色都正确,但内容完全是空的。然后我偶然发现了这个:

view.layout(0, 0, 1080, 1080);
view.invalidate();
view.setDrawingCacheEnabled(true);
view.buildDrawingCache();
Bitmap bmp = view.getDrawingCache();
Bitmap result = bmp.copy(Bitmap.Config.ARGB_8888, false);
view.destroyDrawingCache();
return result;

但同样,它产生了相同的结果:正确的大小和背景颜色,内容为空。我的视图中有很多视图,我在它们上面设置了很多属性,没有空指针等,一切都设置正确。但他们只是没有画出来。为什么会这样?

更新: 正如 psking 所建议的那样,我已将我的绘图逻辑移至 View#post 但它仍然是相同的(尽管触发完成需要更长的时间,这可能是视图实际做某事的线索)。尝试了两种方法:

(补全是我的函数,需要一个位图)

final Bitmap result = Bitmap.createBitmap(1080, 1080, Bitmap.Config.ARGB_8888);
final Canvas c = new Canvas(result);
view.layout(0, 0, 1080, 1080);
view.post(new Runnable() {
    @Override
    public void run() {
        view.draw(c);
        completion.call(result);
    }
});

view.layout(0, 0, 1080, 1080);
view.invalidate();
view.setDrawingCacheEnabled(true);
view.post(new Runnable() {
    @Override
    public void run() {
        view.buildDrawingCache();
        Bitmap bmp = view.getDrawingCache();
        Bitmap result = bmp.copy(Bitmap.Config.ARGB_8888, false);
        view.destroyDrawingCache();
        completion.call(result);
    }
});

但还是一样

我认为这是因为即使您调用了布局,但直到稍后视图才真正根据视图树进行布局。 onGlobalLayoutChangedListener 可让您收听该事件。

试试这个过程:

  1. 将视图扩展到现有视图树。 (您可能有一个通常隐藏在另一个布局中的框架布局。

  2. 给视图添加一个onGlobalLayoutChangedListener,测量视图并抓取位图。

    ViewTreeObserver vto = view.getViewTreeObserver(); vto.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { @Override public void onGlobalLayout() { view.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED); Bitmap bitmap = Bitmap.createBitmap(view.getMeasuredWidth(), view.getMeasuredHeight(), Bitmap.Config.RGB_565); Canvas canvas = new Canvas(bitmap); canvas.drawColor(Color.WHITE); view.layout(0, 0, view.getMeasuredWidth(), view.getMeasuredHeight()); view.draw(canvas); }};

编辑:对格式设置感到抱歉,缩进工具现在似乎对我不起作用

int sizePixels = 1080;

Bitmap result = Bitmap.createBitmap(sizePixels, sizePixels, Bitmap.Config.ARGB_8888);
Canvas c = new Canvas(result);

// measure view first
int sizeSpec = View.MeasureSpec.makeMeasureSpec(sizePixels, View.MeasureSpec.EXACTLY);
view.measure(sizeSpec, sizeSpec);

// then layout
int width = view.getMeasuredWidth();
int height = view.getMeasuredHeight();
view.layout(0, 0, width, height);

// now you can draw it
view.draw(c);