我试图在TextView
中创建文本的位图。在过去,我使用getDrawingCache
完成了此操作。但是,现在我需要创建一个TextView
的位图,其文本比以前长得多。这导致getDrawingCache
抛出NullPointerException。
虽然我说"更长的文字,"我不是说不合理的长。如果我创建一个600像素宽的24字体TextView,我会得到53行文本的异常(但不是52行)。有解决方法吗?
起初我认为this answer是布局在canvas
上绘制的解决方案。但是,这对我没有用,因为我在编程之前以编程方式创建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(至少不是外部的,但也许这就是内部原因。)
答案 0 :(得分:3)
您可以放弃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;
}