在Canvas(Android)上绘制文本前,如何测量文本的宽度?

138

是否有一种方法可以返回使用drawText()方法在Android画布上绘制文本时,根据用于绘制的Paint,文本的宽度(以像素为单位)?

8个回答

252

21
谢谢,就是这个!我不知道为什么跳过了它。目的只是在屏幕中央绘制文本。不管怎样,我刚意识到我也可以在用于绘制文本的Paint上使用setTextAlign(Align.CENTER),它会将指定的原点移动到所绘制文本的中心。谢谢。 - NioX5199
3
太棒了,谢谢!把涂料的对准功能打开,谁会想到呢……? - Sanjay Manohar
或者你可以将TextView的重力设置为居中。 - yeradis

38
Paint paint = new Paint();
Rect bounds = new Rect();

int text_height = 0;
int text_width = 0;

paint.setTypeface(Typeface.DEFAULT);// your preference here
paint.setTextSize(25);// have this the same as your text size

String text = "Some random text";

paint.getTextBounds(text, 0, text.length(), bounds);

text_height =  bounds.height();
text_width =  bounds.width();

19

补充回答

Paint.measureTextPaint.getTextBounds返回的宽度略有不同。 measureText返回的宽度包括字形的advanceX值填充字符串的开头和结尾。由getTextBounds返回的Rect宽度没有这种填充,因为边界是紧密包裹文本的Rect

来源


7

实际上,有三种不同的方法来测量文本。

GetTextBounds:

val paint = Paint()
paint.typeface = ResourcesCompat.getFont(context, R.font.kaushanscript)
paint.textSize = 500f
paint.color = Color.argb(255, 3, 221, 252)
val contents = "g"
val rect = Rect()
paint.getTextBounds(contents, 0, 1, rect)
val width = rect.width()

测量文本宽度:

val paint = Paint()
paint.typeface = ResourcesCompat.getFont(context, R.font.kaushanscript)
paint.textSize = 500f
paint.color = Color.argb(255, 3, 221, 252)
val contents = "g"
val width = paint.measureText(contents, 0, 1)

和 getTextWidths:

val paint = Paint()
paint.typeface = ResourcesCompat.getFont(context, R.font.kaushanscript)
paint.textSize = 500f
paint.color = Color.argb(255, 3, 221, 252)
val contents = "g"
val rect = Rect()
val arry = FloatArray(contents.length)
paint.getTextBounds(contents, 0, contents.length, rect)
paint.getTextWidths(contents, 0, contents.length, arry)
val width = ary.sum()

请注意,如果您想确定何时将文本换行到下一行,getTextWidths可能会很有用。
measureTextWidth和getTextWidth相等,并具有其他人发布的高级宽度。有些人认为这个空间过多。然而,这非常主观,取决于字体。
例如,从测量文本边界得到的宽度可能看起来太小:

measure text bounds looks small

然而,当添加额外的文本时,一个字母的边界看起来正常:字符串的文本边界测量看起来正常 图片来源于Android开发者自定义画布绘制指南

1

由于字距(字母之间的空格)取决于各个字母序列,因此这可能只适用于像 Courier 这样的等宽字体,并且效果才能令人满意。 - Merk

1
好的,我用不同的方式完成了:
String finalVal ="Hiren Patel";

Paint paint = new Paint();
paint.setTextSize(40);
Typeface typeface = Typeface.createFromAsset(getAssets(), "Helvetica.ttf");
paint.setTypeface(typeface);
paint.setColor(Color.BLACK);
paint.setStyle(Paint.Style.FILL);

Rect result = new Rect();
paint.getTextBounds(finalVal, 0, finalVal.length(), result);

Log.i("Text dimensions", "Width: "+result.width()+"-Height: "+result.height());

希望这可以帮到你。

0
你可以使用 "textPaint.getTextSize()" 来获取文本宽度。

0

这应该可以工作。

fun String.getWidth(fontSize: Float): Float {
    val textPaint = TextPaint()
    textPaint.textSize = fontSize
    textPaint.typeface = Typeface.create(Typeface.DEFAULT, Typeface.BOLD)

    return textPaint.measureText(this)
}

带有换行符的文本的高级应用

fun String.getWidth(fontSize: Float): Float {
    val textPaint = TextPaint()
    textPaint.textSize = fontSize
    textPaint.typeface = Typeface.create(Typeface.DEFAULT, Typeface.BOLD)
    val texts = this.split("\n")
    if (texts.size == 1) {
        return textPaint.measureText(this)
    }

    var finalWidth = 0f
    for (text in texts) {
        val thisLineWidth = text.getWidth(fontSize)
        if (thisLineWidth > finalWidth) {
            finalWidth = thisLineWidth
        }
    }

    return finalWidth
}

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