Android之玩轉(zhuǎn)View(三):使用Paint實現(xiàn)的文字繪制(文字的基線)

使用Paint實現(xiàn)的文字繪制(文字的基線)

請尊重原創(chuàng),轉(zhuǎn)載請注明出處【tianyl】的博客

關(guān)于的Android之玩轉(zhuǎn)View目錄

前言

上篇文章介紹了一些使用Paint和Shader結(jié)合實現(xiàn)的一些特效,不過都是一些圖像繪制方面的,當然,Paint除了能夠進行圖像繪制之外,還有另外一個功能,就是文字的繪制

當然,在學習Paint繪制文字之前,最好能夠熟悉一些Paint繪制文字的api這是Paint繪制文字的常用api說明

1 文字的基線

說到文字繪制,先從一個api說起

drawText(@NonNull String text, float x, float y, @NonNull Paint paint)

這是一個常用的繪制文字的辦法,可能有朋友會遇到,在使用這個方法繪制文字的時候,文字的位置經(jīng)常不對,不是高了,就是低了,這就是由于這個api中的x和y造成的

看圖說明


在我們繪制文字的時候,通常有上圖中的六條線,分別是

  1. top:頂點線
  2. ascent:建議頂點線
  3. center:中心線
  4. baseline:基線
  5. descent:建議底部線
  6. bottom:底部線

這六條線分別起什么作用呢?

  • 首先是top和bottom,這兩條線很好理解,它分別是頂端和底端,繪制文字時肯定不會超過這兩條線
  • 然后是ascent和descent,這兩條線是建議的頂點線和建議底端線,一般情況我們繪制文字是不會超過這兩條線的,但是對于一些異形字(論壇中經(jīng)常出現(xiàn)的跨樓層的字)是可以超出這兩條線的
  • 再則是center線,這條線也很好理解,它就是top和bottom的中心
  • 最后就是基線了,這也是我們繪制文字時,傳入的y坐標

1.1 基線的計算

解釋了上面六條線的作用,接下來再說說這六條線是怎么計算的。

首先,我們要清楚,這六條線都是真實存在的,它們的值就保存在Paint.FontMetricsPaint.FontMetricsInt中,這兩個類的值基本相似,區(qū)別是一個是float,一個是int

如圖

  • Paint.FontMetrics


  • Paint.FontMetricsInt


明確了這六條線值的位置,那它們是怎么計算得來的呢?

首先說明,計算著六條線的時候,是以基線為參照物的,計算方式如下

注:在以下計算推斷中,ascent,desent之類的都表示距離,ascent.y,desent.y之類的表示坐標

top.y = top.y - baseline.y
bottom.y = bottom.y - baseline.y
ascent.y = ascent.y - baseline.y
desent.y = desent.y - baseline.y
center.y = (bottom.y - top.y) / 2

因為是以baseline為參照物,所以所有的距離都是它們的y坐標和baseline的y坐標相減,
但是Paint.FontMetrics中并沒有baseline的值,那么我們要怎么得到它呢

baseline的計算如圖所示(網(wǎng)上好多圖都是錯的,不得不自己畫了一張,(╥﹏╥))

首先,如果我們要繪制文本,那么我們可以拿到top和bottom的坐標,并且我們也知道center

  • center.y = (bottom.y - top.y) / 2

看圖,我們知道top.y到center.y的距離和bottom.y到center.y的距離相同,設(shè)定這個距離為a,那么center.y到baseline.y的距離就是:a - bottom
(沒有.y時表示它到baseline的距離)

所以有:

  • baseline.y - center.y = (bottom.y - top.y) / 2 - bottom.y

解得:

  • baseline.y = center.y + (bottom.y - top.y) / 2 - bottom.y

當然,同樣的推理,還可以得出baseline和ascent,desent之間的關(guān)系,這里就不展開了,原理都是一樣的

1.2 如何繪制文字到中心

經(jīng)歷了前面的長篇大論,有的同學就要問了,知道baseline的計算有什么用呢?

回到最開始的api

drawText(@NonNull String text, float x, float y, @NonNull Paint paint)

是不是有的同學在使用這個api的時候,經(jīng)常遇到y(tǒng)值怎么設(shè)置都不能讓文字處于控件中間,不是高一點就是低一點?

如果我們想把文字繪制到我們View的正中心,那么這里的y就需要傳入我們計算好的baseline,代碼如下

// 首先設(shè)置paint的文字大小
paint.setColor(textColor);
paint.setStrokeWidth(0);
paint.setTextSize(textSize);
paint.setTypeface(Typeface.DEFAULT_BOLD);

//根據(jù)paint的文字大小獲得Paint.FontMetricsInt
Paint.FontMetricsInt fm = paint.getFontMetricsInt();

//根據(jù)Paint.FontMetricsInt計算baseline
canvas.drawText(string, getWidth() / 2 - paint.measureText(string) / 2 ,
            getHeight() / 2  +(fm.bottom - fm.top)/2 - fm.bottom, paint);

這樣,就可以將文字畫到垂直方向的正中心了,至于水平中心,只需要控件寬度減去文字寬度除以2就可以了

本來還想寫一些文字的特效的,想來篇幅太長閱讀起來體驗也不太好,文字的特效就留到以后寫吧

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容