一激才、作用
二取具、概念
1. API
(1)drawText()
// 將字符串[start,end)范圍內(nèi)的字符繪制出來毕箍,繪制起點(diǎn)(x,y)
public void drawText (CharSequence text, int start, int end, float x, float y, Paint paint)
(2)drawTextOnPath()
// 將指定字符沿 path 繪制
public void drawTextOnPath (char[] text, int index, int count, Path path, float hOffset, float vOffset, Paint paint)
(3)drawTextRun()
2. 術(shù)語
(1)基線
(2)行間距倍數(shù)
Android TextView行間距解析
(3)行間距額外增加值
行間距倍數(shù)、行間距額外增加值改變了文字占用的高度肮帐,從而在視覺上形成了行與行之間間隔的效果。
public int getLineHeight() {
return FastMath.round(mTextPaint.getFontMetricsInt(null) * mSpacingMult + mSpacingAdd);
}
(4)和文字繪制相關(guān)的5條線
leading
上行的bottom
和下行的top
線距離捍掺。
3. StaticLayout
(1)作用
Canvas::drawText()
繪制文字時(shí)不能換行:文字不能在 View 邊緣自動(dòng)換行;不能在\n
處換行
StaticLayout
繪制文字時(shí)能換行:文字在 View 邊緣自動(dòng)換行再膳;在\n
處換行
(2)構(gòu)造函數(shù)
StaticLayout(CharSequence source, TextPaint paint, int width, Layout.Alignment align, float spacingmult, float spacingadd, boolean includedpad)
// spacingmult :行間距倍數(shù)挺勿,通常情況下填1就好
// spacingadd:行間距額外增加的數(shù)值,通常情況下填0就好
// includedpad:是指是否在文字上下添加額外的空間喂柒,來避免某些過高的字符的繪制出現(xiàn)越界
4. Paint 對(duì)文字繪制的輔助能力
(1)對(duì)文字繪制的輔助
(2)測(cè)量文字尺寸類
float getFontSpacing()
獲取推薦的行間距不瓶,即兩行文字的baseline
的距離。這個(gè)值是系統(tǒng)根據(jù)文字的字體和字號(hào)自動(dòng)計(jì)算的灾杰。
當(dāng)你需手動(dòng)繪制多行文字(而不是使用StaticLayout
時(shí))蚊丐,可以在換行的時(shí)候給y
坐標(biāo)加上這個(gè)值來下移文字。
FontMetrics getFontMetrics()
提供幾個(gè)文字排版方面的數(shù)值艳吠。
從定義可得麦备,兩行文字的 font spacing(即兩行文字的baseline
的距離),可以通過bottom-top+leading
計(jì)算得出昭娩。
但實(shí)際上
bottom-top+leading
的結(jié)果要大于getFontSpacing()
返回的值凛篙。因?yàn)椋?code>getFontSpacing()不是通過FontMetric
的標(biāo)準(zhǔn)值計(jì)算出來的,而是另外計(jì)算出來的一個(gè)值栏渺,它能夠做到在兩行文字不顯得擁擠的前提下縮短行距呛梆,以此來得到更好的顯示效果。
所以:如果你需要對(duì)文字手動(dòng)換行繪制磕诊,多數(shù)時(shí)候應(yīng)該選取
getFontSpacing()
來得到行距填物,不但使用簡(jiǎn)單,顯示效果也更好秀仲。
void getTextBounds(CharSequence text, int start, int end, Rect bounds)
測(cè)量文字顯示范圍
// text:要測(cè)量的文字
// start:起始位置
// end:結(jié)束位置
// bounds:存儲(chǔ)文字顯示范圍融痛,該方法測(cè)量完后將數(shù)值存儲(chǔ)在該對(duì)象中
float measureText(CharSequence text, int start, int end)
測(cè)量文字寬度并返回
// text:要測(cè)量的文字
// start:起始位置
// end:結(jié)束位置
void getTextWidth(String text, int start, int end, int[] widths)
測(cè)量字符串中每個(gè)字符的寬度壶笼,并將結(jié)果填充到數(shù)組中
int breakText(char[] text, int index, int count, float maxWidth, float[] measuredWidth)
根據(jù)傳入的 maxWidth神僵,測(cè)量出能顯示的最大字符個(gè)數(shù),并返回
三覆劈、使用
1.measureText()
float text1Width = paint1.measureText(text1);
float text2Width = paint2.measureText(text2);
canvas.drawText(text1, 50, 200, paint1);
canvas.drawText(text2, 50 + text1Width, 200, paint2);
canvas.drawText(text3, 50 + text1Width + text2Width, 200, paint1);
2.getTextBounds()
結(jié)合getTextBounds方法簡(jiǎn)析繪制文字時(shí)需要注意的地方
getTextBounds中bounds的坐標(biāo)原點(diǎn)
這種居中算法的優(yōu)點(diǎn)是保礼,可以讓文字精準(zhǔn)地居中,分毫不差
打印A
责语、j
炮障,分別調(diào)用getTextBounds()
返回的結(jié)果
A::top=-114,bot=0,left=2,right=103
j::top=-116,bot=35,left=-6,right=28
- 使用 Paint.getTextBounds() 計(jì)算出文字的顯示區(qū)域
Rect textBounds = new Rect();
paint2.getTextBounds(text, 0, texts.length(), textBounds);
- 計(jì)算出文字的
baseline
的y
坐標(biāo)相對(duì) middle 的偏移量
yOffsets = - (textBounds.top + textBounds.bottom) / 2;
- 繪制文字,讓文字在框中上下居中
canvas.drawRect(50, top, getWidth() - 50, bottom, paint1);
int middle = (top + bottom) / 2;
canvas.drawText(texts, 100, middle + yOffsets, paint2);
3.getFontMetrics()
- 使用 Paint.getFontMetrics() 得到
acent
坤候、decent
Paint.FontMetrics fontMetrics = paint2.getFontMetrics();
- 計(jì)算出文字的
baseline
的y
坐標(biāo)相對(duì) middle 的偏移量(計(jì)算邏輯同上)
yOffset = - (fontMetrics.ascent + fontMetrics.descent) / 2;
- 繪制文字胁赢,讓文字在框中上下居中
canvas.drawRect(50, top, getWidth() - 50, bottom, paint1);
int middle = (top + bottom) / 2;
canvas.drawText(text, 100, middle + yOffset, paint2);