Paint.FontMetrics類簡介
Google文檔中的描
述:
/**
* Class that describes the various各種 metrics指標 for a font at a given text size.
* Remember, Y values increase going down, so those values will be positive正數,
* and values that measure distances距離 going up will be negative負數. This class
* is returned by getFontMetrics().
*/
public static class FontMetrics {
//The maximum distance above the baseline for the tallest glyph in the font at a given text size.
public float top;
//【字符頂部】The recommended推薦的 distance above the baseline for singled spaced text.
public float ascent;
//【字符底部】The recommended distance below the baseline for singled spaced text.
public float descent;
//The maximum distance below the baseline for the lowest glyph in the font at a given text size.
public float bottom;
//【字符行間距】The recommended additional額外的 space to add between lines兩行之間 of text.
public float leading;
}
網上找的各種模型圖
注意Y坐標基准點是在BaseLine那個位置,而非AscentLine或Top那個位置



Paint的ascent和descent方法--算高度
這兩個是native方法
//Return the distance above (negative) the baseline (ascent) based on the current typeface字體 and text size.
public native float ascent();
//Return the distance below (positive) the baseline (descent) based on the current typeface and text size.
public native float descent();
可以通過 mPaint.ascent()+ mPaint.descent() 獲取文字高度
Paint的measureText方法--獲取寬度

/**
* Return the width of the text.
*
* @param text The text to measure. Cannot be null.
* @param start The index of the first character to start measuring
* @param end 1 beyond the index of the last character to measure
* @return The width of the text
*/
public float measureText(String text, int start, int end) {
if (text == null) throw new IllegalArgumentException("text cannot be null");
if ((start | end | (end - start) | (text.length() - end)) < 0) throw new IndexOutOfBoundsException();
if (text.length() == 0 || start == end) return 0f;
if (!mHasCompatScaling) return (float) Math.ceil(native_measureText(text, start, end, mBidiFlags));
final float oldSize = getTextSize();
setTextSize(oldSize*mCompatScaling);
float w = native_measureText(text, start, end, mBidiFlags);
setTextSize(oldSize);
return (float) Math.ceil(w*mInvCompatScaling);
}
通過這個方法即可以輕松的獲取到文字的的寬度
Paint的getTextBounds方法--獲取邊界

/**
* Return in bounds (allocated by the caller 由調用者分配) the smallest最小的 rectangle that
* encloses圍起來 all of the characters, with an implied origin默認的起始位置 at (0,0).
* @param text String to measure and return its bounds
* @param start Index of the first char in the string to measure
* @param end 1 past the last char in the string measure
* @param bounds Returns the unioned bounds of all the text. Must be allocated by the caller.
*/
public void getTextBounds(String text, int start, int end, Rect bounds) {
if ((start | end | (end - start) | (text.length() - end)) < 0) throw new IndexOutOfBoundsException();
if (bounds == null) throw new NullPointerException("need bounds Rect");
nativeGetStringBounds(mNativePaint, mNativeTypeface, text, start, end, mBidiFlags, bounds);
}
這個方法需要提供一個參數 Rect 矩形區域,這個方法將文字的區域傳遞到 Rect
Paint的獲取
比如對於TextView,要通過
TextView的
getPaint()得到
Paint,而不能new一個或者拿其他不相干的
Paint
/**
* @return the base paint used for the text. Please use this only to
* consult查閱 the Paint's properties屬性 and not to change them.
*/
public TextPaint getPaint() {
return mTextPaint;
}
如果是在自定義View 中,則可以
直接
通過Paint調用相關方法去獲取文字的寬高等信息
測試代碼
public class MainActivity extends Activity {
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
String text = "aA bB fF gG";
TextView tv_info = new TextView(this);
tv_info.setTextColor(Color.BLUE);
tv_info.setBackgroundColor(0x5500ff00);
tv_info.setTextSize(TypedValue.COMPLEX_UNIT_SP, 18);
tv_info.setText(text);
setContentView(tv_info);
tv_info.measure(0, 0);//必須手動調用測量方法,否則getMeasuredHeight獲取不到值。另外,即使測量過了getHeight也獲取不到值
Paint mPaint = tv_info.getPaint();
Log.i("bqt", "ascent()的值為" + mPaint.ascent() + ",descent()的值為" + mPaint.descent());//-33.398438, 8.7890625
Log.i("bqt", "字符的高度為" + (-mPaint.ascent() + mPaint.descent()) + ",字符的長度為" + mPaint.measureText(text));//42.1875,190.0
Log.i("bqt", "測量的高度為" + tv_info.getMeasuredHeight() + ",測量的寬度為" + tv_info.getMeasuredWidth());//49,190
Rect mRect = new Rect();
mPaint.getTextBounds(text, 0, text.length(), mRect);
Log.i("bqt", "字符的邊界為" + mRect.left + "," + mRect.top + "," + mRect.right + "," + mRect.bottom);//1,-28,187,8
Log.i("bqt", "字符的高度為" + (mRect.bottom - mRect.top) + ",字符的長度為" + (mRect.right - mRect.left));//36,186
}
}