如何在Android上获取字符串宽度?

116

如果可能的话,我也想获得高度信息。

7个回答

220
你可以使用一个 Paint 对象的 getTextBounds(String text, int start, int end, Rect bounds) 方法。你可以使用由 TextView 提供的 paint 对象,或自己构建一个带有所需文本外观的 paint 对象。
使用 TextView 你可以进行以下操作:
Rect bounds = new Rect();
Paint textPaint = textView.getPaint();
textPaint.getTextBounds(text, 0, text.length(), bounds);
int height = bounds.height();
int width = bounds.width();

5
@Frank:如果这个字符串是一个跨度字符串呢? - Ashwin
很棒的答案。顺便说一下,如果调用textView.setTextSize(),结果会更准确。 - Weiyi

91

9
另外,如果你想以特定字体大小测量文本,可以使用 TextPaint paint = new TextPaint(); paint.setTextSize(textSize);textSize 单位为像素。 - Nathan Reline
获取高度呢? - Prince Dholakiya

21

文本有两种不同的宽度测量方式。一种是绘制宽度所占用的像素数,另一种是绘制文本后光标应该向前移动的“像素”数量。

paint.measureTextpaint.getTextWidths 返回在绘制给定字符串后光标应该向前移动的像素数(以浮点数表示)。要获取绘制像素数,请使用 paint.getTextBounds,如其他答案中所述。我认为这被称为字体的“Advance”。

对于某些字体,这两种测量值可能会(很大程度上)不同,例如字体Black Chancery具有延伸到其他字母之外的字母(重叠)-请参见大写字母'L'。要获取绘制像素数,请使用 paint.getTextBounds,如其他答案中所述。


7

我用以下方法测量宽度:

String str ="Hiren Patel";

Paint paint = new Paint();
paint.setTextSize(20);
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(str, 0, str.length(), result);

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

这将对您有所帮助。


5

很可能您想知道给定字体(即特定的Typeface,例如带有BOLD_ITALIC样式的“sans-serif”字体系列,并具有特定的大小(以sp或px为单位))的给定文本的绘制尺寸。

与其膨胀一个完整的TextView,您可以更低级别地使用Paint对象来处理单行文本,例如:

// Maybe you want to construct a (possibly static) member for repeated computations
Paint paint = new Paint();

// You can load a font family from an asset, and then pick a specific style:
//Typeface plain = Typeface.createFromAsset(assetManager, pathToFont); 
//Typeface bold = Typeface.create(plain, Typeface.DEFAULT_BOLD);
// Or just reference a system font:
paint.setTypeface(Typeface.create("sans-serif",Typeface.BOLD));

// Don't forget to specify your target font size. You can load from a resource:
//float scaledSizeInPixels = context.getResources().getDimensionPixelSize(R.dimen.mediumFontSize);
// Or just compute it fully in code:
int spSize = 18;
float scaledSizeInPixels = TypedValue.applyDimension(
            TypedValue.COMPLEX_UNIT_SP,
            spSize,
            context.getResources().getDisplayMetrics());
paint.setTextSize(scaledSizeInPixels);

// Now compute!
Rect bounds = new Rect();
String myString = "Some string to measure";
paint.getTextBounds(myString, 0, myString.length(), bounds);
Log.d(TAG, "width: " + bounds.width() + " height: " + bounds.height());

对于多行或跨度文本(SpannedString),建议考虑使用StaticLayout,在其中提供宽度并导出高度。关于在自定义视图中测量和绘制文本到画布的详细回答,请参见: https://dev59.com/hVgR5IYBdhLWcg3wEZ2V#41779935

此外,值得注意@arberg在下面的回答中提到的像素绘制与前进宽度(“给定字符串绘制后应该向前移动的像素数(以浮点数表示)”)之间的关系,如果您需要处理此类问题。


5

我想分享一种更好的方法(比当前被接受的答案更通用)来使用静态类 StaticLayout 获取绘制文本(String)的精确宽度:

StaticLayout.getDesiredWidth(text, textPaint))

这种方法比textView.getTextBounds()更精确,因为您可以计算多行TextView中单行的宽度,或者您可能根本不使用TextView(例如在自定义View实现中)。

这种方法类似于textPaint.measureText(text),但在极少数情况下似乎更准确。


-1

我只是在行中取最大字符,并用最大空格分隔并创建新行。

    v_y = v_y + 30;
    String tx = "مبلغ وقدرة : "+ AmountChar+" لا غير";

    myPaint.setTextAlign(Paint.Align.RIGHT);

    int pxx = 400;
    int pxy = v_y ;
    int word_no = 1;
    int word_lng = 0;
    int max_word_lng = 45;
    int new_line = 0;
    int txt_lng = tx.length();
    int words_lng =0;
    String word_in_line = "" ;
    for (String line : tx.split(" "))
    {
        word_lng = line.length() ;
        words_lng += line.length() + 1;

        if (word_no == 1 )
        {word_in_line = line;
        word_no += 1;
        }
        else
            { word_in_line += " " + line;
            word_no += 1;
            }

        if (word_in_line.length() >= max_word_lng)
       {
           canvas.drawText(word_in_line, pxx, pxy, myPaint);
            new_line += 1;
            pxy = pxy + 30;
            word_no = 1;
            word_in_line = "";
        }
        if (txt_lng <= words_lng )
        { canvas.drawText(word_in_line, pxx, pxy, myPaint); }
    }

    v_y = pxy;

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