调用getDrawingCache()时,视图太大无法适应绘图缓存。

5

我想截取LinearLayout的内容并进行截图。该布局包含一个可变高度和宽度的滚动视图。当布局不太大时(即您无需向下滚动很多屏幕才能查看所有内容),此代码运行良好:

View v1 = (LinearLayout)theLayout;

v1.setDrawingCacheEnabled(true);
Bitmap bitmap = Bitmap.createBitmap(v1.getDrawingCache());
v1.setDrawingCacheEnabled(false);

然而,如果我想要截取的LinearLayout很大,应用程序就会在v1.getDrawingCache()上出现空指针而崩溃。

logcat中出现了错误:

05-11 13:16:20.999: W/View(17218): View too large to fit into drawing cache, needs 4784400 bytes, only 3932160 available

如何正确地截取此布局的屏幕截图?是否有其他方法不需要使用太多内存来进行操作?


1
请查看kameltreiber的回答:https://dev59.com/dmkw5IYBdhLWcg3wlbh3。 - Raghunandan
我尝试了这里的被接受的答案,但生成的输出存在一些问题。这里的答案才是对我有用的:https://stackoverflow.com/a/44129753/5987223 - drishit96
2个回答

13

以下是最终对我有效的方法,完整地捕获了大型离屏视图:

public static Bitmap loadBitmapFromView(View v) 
{
    Bitmap b = Bitmap.createBitmap(v.getWidth(), v.getHeight(), Bitmap.Config.ARGB_8888);

    Canvas c = new Canvas(b);
    v.layout(0, 0, v.getLayoutParams().width, v.getLayoutParams().height);
    v.draw(c);
    return b;
}

这与 这里 的答案类似,只是我使用视图的宽度/高度来创建位图


1
为确保在所有情况下都能正常运行,您还应在layout()之前调用measure()方法。 - Romain Guy
只是补充一下,这也适用于完全不可见的视图(visibility == invisible),这正是我的情况。 - dragi
如果我想要改变生成的 Bitmap 的尺寸怎么办? - Evgeny Fedin

1

由于原问题涉及到ScrollView,我想为那些在获取完整高度时遇到问题的人添加以下内容。要获取ScrollView的高度,v.getHeight无效,你需要使用:

v.getChildAt(0).getHeight()

"所以完整的内容应该是:

ScrollView scrollView = (ScrollView) result.findViewById(R.id.ScrlView);

loadBitmapFromView(scrollView);

public static Bitmap loadBitmapFromView(View v) 
{
int height = v.getChildAt(0).getHeight()
int width = v.getWidth()
Bitmap b = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);

Canvas c = new Canvas(b);
v.layout(0, 0, v.getLayoutParams().width, v.getLayoutParams().height);
v.draw(c);
return b;
}

仅使用v.getHeight只能获取屏幕高度,无法获取ScrollView的完整高度。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接