Android drawText including text wrapping
Solution 1
Yes, StaticLayout
is what you're meant to use to draw multi-line text on a Canvas
. Save yourself a world of pain and don't think about breaking text yourself -- you're on the right path.
I'm not sure about the bitmap problem, but your second code above worked just fine to draw text on a canvas for me.
Learn to use StaticLayout
, then draw the Layout object onto a canvas using the Layout.draw()
method.
References
Solution 2
public Bitmap drawMultilineTextToBitmap(Context gContext,
int gResId,
String gText) {
// prepare canvas
Resources resources = gContext.getResources();
float scale = resources.getDisplayMetrics().density;
Bitmap bitmap = BitmapFactory.decodeResource(resources, gResId);
android.graphics.Bitmap.Config bitmapConfig = bitmap.getConfig();
// set default bitmap config if none
if(bitmapConfig == null) {
bitmapConfig = android.graphics.Bitmap.Config.ARGB_8888;
}
// resource bitmaps are imutable,
// so we need to convert it to mutable one
bitmap = bitmap.copy(bitmapConfig, true);
Canvas canvas = new Canvas(bitmap);
// new antialiased Paint
TextPaint paint=new TextPaint(Paint.ANTI_ALIAS_FLAG);
// text color - #3D3D3D
paint.setColor(Color.rgb(61, 61, 61));
// text size in pixels
paint.setTextSize((int) (14 * scale));
// text shadow
paint.setShadowLayer(1f, 0f, 1f, Color.WHITE);
// set text width to canvas width minus 16dp padding
int textWidth = canvas.getWidth() - (int) (16 * scale);
// init StaticLayout for text
StaticLayout textLayout = new StaticLayout(
gText, paint, textWidth, Layout.Alignment.ALIGN_CENTER, 1.0f, 0.0f, false);
// get height of multiline text
int textHeight = textLayout.getHeight();
// get position of text's top left corner
float x = (bitmap.getWidth() - textWidth)/2;
float y = (bitmap.getHeight() - textHeight)/2;
// draw text to the Canvas center
canvas.save();
canvas.translate(x, y);
textLayout.draw(canvas);
canvas.restore();
return bitmap;
}
source : http://www.skoumal.net/en/android-drawing-multiline-text-on-bitmap/
Related videos on Youtube
Mustafa Nasser
Updated on June 04, 2022Comments
-
Mustafa Nasser about 2 years
I am currently creating an image editor and am attempting to draw text on top of on image using canvas.drawText(). So far I have been successful in doing this but when the user enters text that is too long, the text just continues on one line out of the page and doesn't wrap itself to the width of the screen. How would I go about doing this? I have tried using a static layout but cannot seem to get it to work, has anyone got a tutorial to do this?
My function for drawing on a canvas using static layout:
public Bitmap createImage(float scr_x,float scr_y,String user_text){ Canvas canvas = new Canvas(image); scr_x = 100; scr_y = 100; final TextPaint tp = new TextPaint(Color.WHITE); canvas.save(); StaticLayout sl = new StaticLayout("" + user_text, tp, originalBitmap.getWidth(), Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false); sl.draw(canvas); return image; }
Okay, I've updated my code, but when I try to draw on the image nothing happens at all, I have no idea why either:
public Bitmap createImage(String user_text) { // canvas object with bitmap image as constructor Canvas canvas = new Canvas(image); TextPaint tp = new TextPaint(); tp.setColor(Color.RED); tp.setTextSize(50); tp.setTextAlign(Align.CENTER); tp.setAntiAlias(true); StaticLayout sl = new StaticLayout("" + user_text, tp, canvas.getWidth(), Layout.Alignment.ALIGN_NORMAL, 1, 0, false); canvas.translate(100, 100); sl.draw(canvas); return image; }
Is staticlayout not meant to be used to draw on canvas?
-
Joshua Pinter about 9 yearsTake a look at this other answer for a good usage example of
StaticLayout
s: stackoverflow.com/a/8369690/293280 -
Joshua Pinter about 9 yearspossible duplicate of Draw multi-line text to Canvas
-
-
Mustafa Nasser almost 11 yearsHow do you mean? I'm really struggling with this as I'm pretty new. It seems from reading all other threads that the StaticLayout method is preferred?
-
Marcos Vasconcelos almost 11 yearsComponents that do extends View will not drawn anything until layout and measure is called, may you need call sl.measure(100,100,width, height) then draw. But I know that measuring characters width to wrap content can be done.
-
Lisa Wray almost 11 yearsStaticLayout is specifically meant for rendering multi-line text, including handling line breaking for you. You should absolutely use it to draw text on a Canvas in any case where you "would be tempted to call Canvas.drawText() directly". Trust me, you do NOT want to get into your own line breaking. developer.android.com/reference/android/text/StaticLayout.html
-
Marcos Vasconcelos almost 11 yearsNice to know Lisa, just dont see a reason to downvote, but thanks anyway, will be helpfull for me also.
-
Marcos Vasconcelos almost 11 yearsPlease provide a sample, since StaticLayout dont has any direct draw method to a Canvas (and Canvas dont has any draw(text.layout))
-
Marcos Vasconcelos almost 11 yearsAlso my answer is correct, but it's not the best way.. just to you to see how unfair this is
-
Mustafa Nasser almost 11 yearsI can confirm Marcos solution does indeed work, I forgot to add the following line at the end, iv_ttx.setImageBitmap(image).....Thank you Marco.
-
IntoTheDeep almost 8 yearsThis answer did not help at all