androidviewandroid-viewandroid-4.0-ice-cream-sandwichoff-screen

Android offscreen view draws only its background and nothing else


I'm trying to create and render a view completely offscreen. First, I've tried (from 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;

It rendered only my view's background color. It's the correct size and correct background color, but the contents are completely empty. Then I've stumbled upon this:

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;

But again, it yields the same result: correct size and background color with empty contents. There are many views inside my view, I set many properties on them, there are no null pointers etc, everything gets set correctly. But they are just not drawn. Why would this happen?

UPDATE: As psking suggested, I've moved my drawing logic to View#post but it's still the same (though it takes longer to fire the completion, which may be a clue to the view actually doing something). Tried both methods:

(completion is my function that takes a Bitmap)

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

and

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

But still the same.


Solution

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