【问题标题】:Android Programming: How to draw multiline text in a rectangle?Android 编程:如何在矩形中绘制多行文本?
【发布时间】:2012-10-16 18:06:35
【问题描述】:

我看过很多处理类似问题的帖子,但没有一个对我有用。在Canvas 中,我有一个大小为 200 像素 x 200 像素的矩形,我想在这个矩形中写入文本。文本不需要填满整个矩形,但重要的是当它到达矩形的末尾时应该自动换行。如何在 Android 中做到这一点?

【问题讨论】:

  • 我认为将 TextView 包装在您可以轻松完成的自定义布局中并将 TextView 的宽度和高度设置为“fill_parent”的更好解决方案。它符合您的目的。:)

标签: android android-layout android-canvas


【解决方案1】:

您可以使用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();

【讨论】:

  • 谢谢!我以前从未遇到过 StaticLayout,我可以用它来清理我的应用程序中的一些丑陋的代码。
  • 如果之后需要更改文字,也可以将StaticLayout替换为DynamicLayout。
  • @LouisCAD 我没有看到任何在创建对象后编辑文本的方法。此类中没有设置器。
  • @RamizAnsari 你是对的,但是你在DynamicLayout 构造函数中传递的CharSequence 可以在之后进行编辑。例如,它可以采用 Editable,或者您的 CharSequence 实现,该实现委托给您可以交换的字符串。
【解决方案2】:

您需要测量文本,然后在代码中自行分解。 Paint.measureText 是你需要的。

【讨论】:

    【解决方案3】:
    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());
    }
    

    【讨论】:

    • 请没有代码只回答,添加 cmets 来解释你在做什么。
    【解决方案4】:

    您是否可以在画布顶部使用一个文本字段并为该文本字段启用多行 - 然后您会像在文本字段中免费提供换行符一样完成 ;-)

    【讨论】:

      猜你喜欢
      • 2011-10-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-03-22
      • 2015-11-15
      • 2021-06-30
      • 2012-07-02
      • 1970-01-01
      相关资源
      最近更新 更多