使用 getDrawingCache 时是否有最大位图大小? [英] Is there a maximum bitmap size when using getDrawingCache?
问题描述
我正在尝试在 TextView
中创建文本的位图.过去,我使用 getDrawingCache
完成了此操作.但是,现在我需要创建一个 TextView
的位图,其中的文本比以前长得多.这导致 getDrawingCache
抛出 NullPointerException.
I'm trying to create a bitmap of the text in a TextView
. In the past I have done this using getDrawingCache
. However, now I have a need to create a bitmap of a TextView
with much longer text than before. This is causing getDrawingCache
to throw a NullPointerException.
虽然我说的是更长的文本",但我并不是在说不合理的长.如果我创建一个宽度为 600 像素、字体大小为 24 的 TextView,我会在 53 行文本(但不是 52 行)处得到异常.有解决方法吗?
Although I say "much longer text," I am not talking about unreasonably long. If I create a TextView that is 600 pixels wide at size 24 font, I get the exception at 53 lines of text (but not at 52 lines). Is there a workaround for this?
起初我想到了这个答案,其中布局在画布
上绘制自己,是解决方案.但是,这对我不起作用,因为我正在以编程方式创建 TextView 并且 宽度和高度在布局之前都是 0.我从来没有真正在屏幕上布置过我的 TextView
.
At first I thought this answer, in which the layout draws itself on a canvas
, was the solution. However, that didn't work for me because I am creating the TextView programmatically and the width and height are 0 before they get laid out. I never actually layout my TextView
on screen.
private Bitmap getBitmap(Context context){
final int NUMBER_OF_LINES = 53; // 53 crashes, 52 doesn't
final int width = 600; // width of TextView in pixels
final int fontSize = 24;
// create string with NUMBER_OF_LINES
StringBuilder testString = new StringBuilder();
for (int i = 0; i < NUMBER_OF_LINES; i++) {
testString.append("
");
}
// Create TextView
TextView tvText = new TextView(context);
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.WRAP_CONTENT,
LinearLayout.LayoutParams.WRAP_CONTENT);
tvText.setTextSize(fontSize);
tvText.setWidth(width);
tvText.setLayoutParams(params);
tvText.setBackgroundColor(Color.WHITE); // even setting the background color affects crashing or not
tvText.setText(testString);
// Create bitmap
tvText.setDrawingCacheEnabled(true);
tvText.measure(View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED),
View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));
tvText.layout(0, 0, tvText.getMeasuredWidth(), tvText.getMeasuredHeight());
tvText.buildDrawingCache(true);
Bitmap bitmap = Bitmap.createBitmap(tvText.getDrawingCache()); // crashes here
tvText.setDrawingCacheEnabled(false);
// This also didn't work because width and height are 0
/*Bitmap bitmap = Bitmap.createBitmap(tvText.getWidth(), tvText.getHeight(),
Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
tvText.draw(canvas);*/
return bitmap;
}
空指针异常
06-21 14:20:24.628 8036-8036/com.example.testsomecode E/AndroidRuntime﹕ FATAL EXCEPTION: main
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.testsomecode/com.example.testsomecode.MainActivity}: java.lang.NullPointerException
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2092)
...
Caused by: java.lang.NullPointerException
at android.graphics.Bitmap.createBitmap(Bitmap.java:494)
at com.example.testsomecode.MainActivity.getBitmap(MainActivity.java:57) // -> Bitmap bitmap = Bitmap.createBitmap(tvText.getDrawingCache());
at com.example.testsomecode.MainActivity.onCreate(MainActivity.java:25)
...
注意
这不是 IllegalArgumentException 或 OutOfMemoryError(至少不是外部的,尽管这可能是内部的原因.)
Note
This is not an IllegalArgumentException or OutOfMemoryError (At least not externally, though maybe this is the reason internally.)
推荐答案
您可以删除 buildDrawingCache
方法而只使用 canvas
.由于您是以编程方式构建视图,因此您还需要在获取位图之前调用 measure()
和 layout()
.
You can drop the buildDrawingCache
method and just use canvas
. Since you are building the view programmatically you also need to call measure()
and layout()
before you can get a bitmap.
关键行是:
tvText.measure(View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED),
View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));
tvText.layout(0, 0, tvText.getMeasuredWidth(), tvText.getMeasuredHeight());
Bitmap bitmap = Bitmap.createBitmap(tvText.getWidth(), tvText.getHeight(),
Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
tvText.draw(canvas);
这里是完整的例子:
private Bitmap getBitmap(Context context){
final int NUMBER_OF_LINES = 153;
final int width = 600;
final int fontSize = 24;
// create string with NUMBER_OF_LINES
StringBuilder testString = new StringBuilder();
for (int i = 0; i < NUMBER_OF_LINES; i++) {
testString.append("
");
}
// Create TextView
TextView tvText = new TextView(context);
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.WRAP_CONTENT,
LinearLayout.LayoutParams.WRAP_CONTENT);
tvText.setTextSize(fontSize);
tvText.setWidth(width);
tvText.setLayoutParams(params);
tvText.setBackgroundColor(Color.WHITE); // even setting the background color affects crashing or not
tvText.setText(testString);
tvText.measure(View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED),
View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));
tvText.layout(0, 0, tvText.getMeasuredWidth(), tvText.getMeasuredHeight());
// Create the bitmap from the view
Bitmap bitmap = Bitmap.createBitmap(tvText.getWidth(), tvText.getHeight(),
Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
tvText.draw(canvas);
return bitmap;
}
这篇关于使用 getDrawingCache 时是否有最大位图大小?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!