我正在尝试在TextView中创建文本的位图.在过去,我使用getDrawingCache完成了这项工作.但是,现在我需要使用比以前更长的文本来创建TextView的位图.这导致getDrawingCache抛出NullPointerException.
虽然我说“文字长得多”,但我并不是说不合理的长篇.如果我创建一个600像素宽的24字体TextView,我会得到53行文本的异常(但不是52行).这有解决方法吗?
起初我认为this answer是一种解决方案,其中布局在画布上绘制.但是,这对我来说不起作用,因为我在编程之前以编程方式创建了TextView,并且在它们布局之前是the width and height are 0.我从来没有在屏幕上实际布局我的TextView.
代码供参考
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("\n");
}
// 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(至少不是外部的,尽管这可能是内部的原因.)
> Mysterious stacktrace in Android developer console (bitmap size exceeds 32bits)
> Strange out of memory issue while loading an image to a Bitmap object
解决方法:
您可以删除buildDrawingCache方法并使用canvas.由于您以编程方式构建视图,因此在获取位图之前还需要调用measure()和layout().
关键是:
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("\n");
}
// 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;
}