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 可让您收听该事件。
试试这个过程:
将视图扩展到现有视图树。 (您可能有一个通常隐藏在另一个布局中的框架布局。
给视图添加一个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);
我正在尝试创建和渲染一个完全离屏的视图。首先,我尝试过(来自 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 可让您收听该事件。
试试这个过程:
将视图扩展到现有视图树。 (您可能有一个通常隐藏在另一个布局中的框架布局。
给视图添加一个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);