对于某些字体,这两个测量值不同(很多),例如字体 Black Chancery 的字母超出了另一个字体字母(重叠)- 请参阅大写“L”。使用其他答案中提到的 paint.getTextBounds 来绘制像素。
There are two different width measures for a text. One is the number of pixels which has been drawn in the width, the other is the number of 'pixels' the cursor should be advanced after drawing the text.
paint.measureText and paint.getTextWidths returns the number of pixels (in float) which the cursor should be advanced after drawing the given string. For the number of pixels painted use paint.getTextBounds as mentioned in other answer. I believe this is called the 'Advance' of the font.
For some fonts these two measurements differ (alot), for instance the font Black Chancery have letters which extend past the other letters (overlapping) - see the capital 'L'. Use paint.getTextBounds as mentioned in other answer to get pixels painted.
// 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());
Most likely you want to know the painted dimensions for a given string of text with a given font (i.e. a particular Typeface such as the “sans-serif” font family with a BOLD_ITALIC style, and particular size in sp or px).
Rather than inflating a full-blown TextView, you can go lower level and work with a Paint object directly for single-line text, for example:
// 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());
For multi-line or spanned text (SpannedString), consider using a StaticLayout, in which you provide the width and derive the height. For a very elaborate answer on measuring and drawing text to a canvas in a custom view doing that, see: https://stackoverflow.com/a/41779935/954643
Also worth noting @arberg's reply below about the pixels painted vs the advance width ("number of pixels (in float) which the cursor should be advanced after drawing the given string"), in case you need to deal with that.
I'd like to share a better way (more versatile then the current accepted answer) of getting the exact width of a drawn text (String) with the use of static class StaticLayout:
StaticLayout.getDesiredWidth(text, textPaint))
this method is more accurate than textView.getTextBounds(), since you can calculate width of a single line in a multiline TextView, or you might not use TextView to begin with (for example in a custom View implementation).
This way is similar to textPaint.measureText(text), however it seems to be more accurate in rare cases.
发布评论
评论(7)
您可以使用
Paint 对象的 getTextBounds(String text, int start, int end, 矩形边界)
方法。您可以使用TextView
提供的绘制对象,也可以根据您想要的文本外观自行构建一个绘制对象。使用 Textview 您可以执行以下操作:
You can use the
getTextBounds(String text, int start, int end, Rect bounds)
method of a Paint object. You can either use the paint object supplied by aTextView
or build one yourself with your desired text appearance.Using a Textview you Can do the following:
如果您只需要宽度,可以使用:
http://developer.android.com/reference/android/graphics/Paint.html#measureText(java.lang.String)
If you just need the width you can use:
http://developer.android.com/reference/android/graphics/Paint.html#measureText(java.lang.String)
文本有两种不同的宽度度量。一是在宽度上绘制的像素数,另一个是绘制文本后光标应前进的“像素”数。
paint.measureText 和 paint.getTextWidths 返回绘制给定字符串后光标应前进的像素数(以浮点形式表示)。对于绘制的像素数,请使用其他答案中提到的paint.getTextBounds。我相信这被称为字体的“高级”。
对于某些字体,这两个测量值不同(很多),例如字体 Black Chancery 的字母超出了另一个字体字母(重叠)- 请参阅大写“L”。使用其他答案中提到的 paint.getTextBounds 来绘制像素。
There are two different width measures for a text. One is the number of pixels which has been drawn in the width, the other is the number of 'pixels' the cursor should be advanced after drawing the text.
paint.measureText and paint.getTextWidths returns the number of pixels (in float) which the cursor should be advanced after drawing the given string. For the number of pixels painted use paint.getTextBounds as mentioned in other answer. I believe this is called the 'Advance' of the font.
For some fonts these two measurements differ (alot), for instance the font Black Chancery have letters which extend past the other letters (overlapping) - see the capital 'L'. Use paint.getTextBounds as mentioned in other answer to get pixels painted.
我用这种方式测量了宽度:
这会对你有帮助。
I have measured width in this way:
This would help you.
您很可能想知道具有给定字体的给定文本字符串的绘制尺寸(即特定的
字体
,例如具有 BOLD_ITALIC 样式的“sans-serif”字体系列,以及特定尺寸(以 sp 或 px 为单位)。您可以进入较低级别并使用 TextView "noreferrer">
Paint
对象直接用于单行文本,例如:对于多行或跨行文本 (< code>SpannedString),请考虑使用
StaticLayout
,在其中提供宽度并导出高度。有关在自定义视图中测量文本并将文本绘制到画布上的详细答案,请参阅:https://stackoverflow.com/ a/41779935/954643另外值得注意的是 @arberg 下面关于绘制的像素与前进宽度的回复(“绘制给定字符串后光标应前进的像素数(以浮点数表示)”),以防万一需要处理这个问题。
Most likely you want to know the painted dimensions for a given string of text with a given font (i.e. a particular
Typeface
such as the “sans-serif” font family with a BOLD_ITALIC style, and particular size in sp or px).Rather than inflating a full-blown
TextView
, you can go lower level and work with aPaint
object directly for single-line text, for example:For multi-line or spanned text (
SpannedString
), consider using aStaticLayout
, in which you provide the width and derive the height. For a very elaborate answer on measuring and drawing text to a canvas in a custom view doing that, see: https://stackoverflow.com/a/41779935/954643Also worth noting @arberg's reply below about the pixels painted vs the advance width ("number of pixels (in float) which the cursor should be advanced after drawing the given string"), in case you need to deal with that.
我想分享一种更好的方法(比当前接受的答案更通用)使用静态类获取绘制文本(
String
)的精确宽度StaticLayout
:此方法比
textView.getTextBounds()
更准确,因为您可以计算多行TextView
中单行的宽度,或者您可能不会一开始就使用TextView
(例如在自定义View
实现中)。这种方式与
textPaint.measureText(text)
类似,但在极少数情况下似乎更准确。I'd like to share a better way (more versatile then the current accepted answer) of getting the exact width of a drawn text (
String
) with the use of static classStaticLayout
:this method is more accurate than
textView.getTextBounds()
, since you can calculate width of a single line in a multilineTextView
, or you might not useTextView
to begin with (for example in a customView
implementation).This way is similar to
textPaint.measureText(text)
, however it seems to be more accurate in rare cases.simplay 我在行中添加最大字符并用最大空间挑战它并创建新行
simplay i tack max charcter in the line and defieded it with max space and create new line