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

11

我看到许多帖子都在处理类似的问题,但是它们都对我没用。在Canvas中,我有一个大小为200像素乘以200像素的矩形,我想在这个矩形中写字。文字不需要填满整个矩形,但是重要的是当它到达矩形的末端时应该自动换行。如何在Android中实现这一点?


我认为更好的解决方案是将TextView包装在自定义布局中,您可以轻松地设置TextView的宽度和高度为“fill_parent”。这符合您的目的。 :) - Daniel Conde Marin
4个回答

34

你可以使用StaticLayout

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();

2
谢谢!我以前从未接触过StaticLayout,现在我可以使用它来清理我的应用程序中一些丑陋的代码。 - Simon
如果您需要更改文本,也可以使用DynamicLayout来替换StaticLayout。 - Louis CAD
@LouisCAD,我没有看到任何在创建对象后编辑文本的方法。这个类中也没有setter。 - Ramiz Ansari
@RamizAnsari 你说得对,不过在 DynamicLayout 构造函数中传递的 CharSequence 可以在之后进行编辑。例如,它可以接受一个 Editable,或者是你的 CharSequence 实现,该实现委托给一个可以交换的字符串。 - Louis CAD

3

你需要测量文本,然后在代码中自己进行分割。Paint.measureText 就是你需要的。


1
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());
}

1
请勿提供代码,只需添加注释以解释您正在做什么。 - Guillaume F.

0

你可以在画布上方使用一个文本框,并启用多行文本功能,这样你就可以像文本框一样自由换行了;-)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接