问题
I have a custom control that is doing a lot of 2D drawing straight to the canvas.
Some of this drawing is text, so I am using the Canvas.drawText() method.
I want to draw the text within some bounds - a top-left, certain maximum width, and a maximum number of lines. After drawing the text, I want to know how many lines it took.
Is there a built-in function to draw text within bounds doing the splitting sensibly?
If not, is there a standard recipe for doing so?
回答1:
You can use the android.text.StaticLayout class for this; simply create a StaticLayout for the desired text, alignment, width, etc. and call its draw(Canvas) method to draw to the canvas.
回答2:
You can use Paint.getTextBounds() to measure the size of the entire string or Paint.getTextWidths() to get the width of each character. Then split the string appropriately before drawing it.
回答3:
I had the same problem. One of my first solution is following.
/**
* This function draws the text on the canvas based on the x-, y-position.
* If it has to break it into lines it will do it based on the max width
* provided.
*
* @author Alessandro Giusa
* @version 0.1, 14.08.2015
* @param canvas
* canvas to draw on
* @param paint
* paint object
* @param x
* x position to draw on canvas
* @param y
* start y-position to draw the text.
* @param maxWidth
* maximal width for break line calculation
* @param text
* text to draw
*/
public static void drawTextAndBreakLine(final Canvas canvas, final Paint paint,
final float x, final float y, final float maxWidth, final String text) {
String textToDisplay = text;
String tempText = "";
char[] chars;
float textHeight = paint.descent() - paint.ascent();
float lastY = y;
int nextPos = 0;
int lengthBeforeBreak = textToDisplay.length();
do {
lengthBeforeBreak = textToDisplay.length();
chars = textToDisplay.toCharArray();
nextPos = paint.breakText(chars, 0, chars.length, maxWidth, null);
tempText = textToDisplay.substring(0, nextPos);
textToDisplay = textToDisplay.substring(nextPos, textToDisplay.length());
canvas.drawText(tempText, x, lastY, paint);
lastY += textHeight;
} while(nextPos < lengthBeforeBreak);
}
What is missing:
- No intelligent break-line mechanism, since it breaks based on the maxWidth
How to call?
paint.setTextSize(40);
paint.setColor(Color.WHITE);
paint.setSubpixelText(true);
float textHeight = paint.descent() - paint.ascent();
CanvasUtils.drawTextAndBreakLine(canvas, paint, this.left,
textHeight, this.displayWidth, this.text);
I have a static class called CanvasUtils where I encapsulate stuff like this. Basically I draw the text within a rectangle. This is the reason textHeight is the height of the text. But you can pass what you want to the function.
Good programming!
来源:https://stackoverflow.com/questions/2336938/wrapping-long-text-on-an-android-canvas