Android编程:如何在矩形中绘制多行文本?

Android编程:如何在矩形中绘制多行文本?,android,android-layout,android-canvas,Android,Android Layout,Android Canvas,我看到过许多处理类似问题的帖子,但没有一篇适合我。在Canvas中,我有一个大小为200px x 200px的矩形,我想在这个矩形中写入文本。文本不需要填充整个矩形,但重要的是当它到达矩形的末端时,应该自动有一个换行符。在Android中如何实现这一点?您需要测量文本,然后自己在代码中分解文本。是您所需要的。您可以在画布上使用一个textfield并为该textfield启用多行功能吗?然后您可以像在textfield中一样免费使用换行符;-) 您可以使用 公共类多行文本{ 私有字符串多行文字;

我看到过许多处理类似问题的帖子,但没有一篇适合我。在
Canvas
中,我有一个大小为200px x 200px的矩形,我想在这个矩形中写入文本。文本不需要填充整个矩形,但重要的是当它到达矩形的末端时,应该自动有一个换行符。在Android中如何实现这一点?

您需要测量文本,然后自己在代码中分解文本。是您所需要的。

您可以在画布上使用一个textfield并为该textfield启用多行功能吗?然后您可以像在textfield中一样免费使用换行符;-)

您可以使用

公共类多行文本{
私有字符串多行文字;
私有int fontSize=50;
公共多行文本(字符串文本){
this.mText=文本;
}
公共字符串getText(){
返回多行文字;
}
公共void setText(字符串文本){
多行文字=文本;
}
公共空白绘图(画布、矩形绘图空间){
油漆油漆文本=新油漆(油漆.防油漆别名标志);
paintText.setAntiAlias(true);
paintText.setDither(true);
paintText.setColor(Color.BLACK);
paintText.setStyle(Paint.Style.FILL);
paintText.设置行程宽度(3);
paintText.setTextSize(fontSize);
drawMultilineText(多行文字、drawSpace.left、drawSpace.top+15、paintText、canvas、fontSize、drawSpace);
}
私有void drawMultilineText(字符串str、int x、int y、绘画、画布、int fontSize、Rect drawSpace){
int lineHeight=0;
int-yoffset=0;
字符串[]行=str.split(“\n”);
线宽=(int)(从fontSize计算线宽(str,fontSize)*1.4);
字符串行=”;
对于(int i=0;i
我认为将TextView包装在自定义布局中是一个更好的解决方案,您可以轻松完成,并将TextView的宽度和高度设置为“填充父视图”。它符合你的目的。:)谢谢!我以前从未遇到过StaticLayout,我可以用它来清理我应用程序中的一些乱七八糟的代码。如果以后需要更改文本,你也可以用替换StaticLayout。@LouisCAD创建对象后,我看不到任何编辑文本的方法。此类中没有setter。@RamizAnsari但是,您是对的,您传入的
DynamicLayout
构造函数
CharSequence
可以在以后进行编辑。它可以以
Editable
为例,或者您的
CharSequence
实现委托给您可以交换的字符串。没有代码只回答问题,请添加注释解释您在做什么。
RectF rect = new RectF(....)

StaticLayout sl = new StaticLayout("This is my text that must fit to a rectangle", textPaint, (int)rect.width(), Layout.Alignment.ALIGN_CENTER, 1, 1, false);

canvas.save();
canvas.translate(rect.left, rect.top);
sl.draw(canvas);
canvas.restore();
public class MutilineText {
private String mText;
private int fontSize = 50;


public MutilineText(String text) {

    this.mText = text;
}

public String getText() {
    return mText;
}

public void setText(String text) {
    mText = text;
}

public void draw(Canvas canvas, Rect drawSpace) {


    Paint paintText = new Paint(Paint.ANTI_ALIAS_FLAG);

    paintText.setAntiAlias(true);
    paintText.setDither(true);
    paintText.setColor(Color.BLACK);
    paintText.setStyle(Paint.Style.FILL);
    paintText.setStrokeWidth(3);
    paintText.setTextSize(fontSize);
    drawMultilineText(mText, drawSpace.left, drawSpace.top + 15, paintText, canvas, fontSize, drawSpace);
}


private void drawMultilineText(String str, int x, int y, Paint paint, Canvas canvas, int fontSize, Rect drawSpace) {
    int lineHeight = 0;
    int yoffset = 0;
    String[] lines = str.split("\n");

    lineHeight = (int) (calculateHeightFromFontSize(str, fontSize) * 1.4);
    String line = "";
    for (int i = 0; i < lines.length; ++i) {
        if (calculateWidthFromFontSize(line, fontSize) <= drawSpace.width()) {
            canvas.drawText(line, x + 30, y + yoffset, paint);
            yoffset = yoffset + lineHeight;
            line = lines[i];
        } else {
            canvas.drawText(divideString(line, drawSpace.width()), x + 30, y + yoffset, paint);
        }
    }


}

private String divideString(String inputString, int bound) {
    String ret = inputString;

    while (calculateWidthFromFontSize(ret, fontSize) >= bound) {
        ret = ret.substring(0, (ret.length() - 1));
    }
    ret = ret.substring(0, ret.length() - 3) + "...";

    return ret;
}

private int calculateWidthFromFontSize(String testString, int currentSize) {
    Rect bounds = new Rect();
    Paint paint = new Paint();
    paint.setTextSize(currentSize);
    paint.getTextBounds(testString, 0, testString.length(), bounds);

    return (int) Math.ceil(bounds.width());
}

private int calculateHeightFromFontSize(String testString, int currentSize) {
    Rect bounds = new Rect();
    Paint paint = new Paint();
    paint.setTextSize(currentSize);
    paint.getTextBounds(testString, 0, testString.length(), bounds);

    return (int) Math.ceil(bounds.height());
}