Canvas drawText文字垂直居中方案

最近繪制自定義view時(shí)赫舒,用到畫(huà)筆繪制文本,針對(duì)drawText的繪制做一些總結(jié)唐全。

Canvas.drawText的方法定義如下:

    /**
     * Draw the text, with origin at (x,y), using the specified paint. The origin is interpreted
     * based on the Align setting in the paint.
     *
     * @param text The text to be drawn
     * @param x The x-coordinate of the origin of the text being drawn
     * @param y The y-coordinate of the baseline of the text being drawn
     * @param paint The paint used for the text (e.g. color, size, style)
     */
    public void drawText(@NonNull String text, float x, float y, @NonNull Paint paint) {
        super.drawText(text, x, y, paint);
    }

其中埃跷,x坐標(biāo)比較好理解,是文本起始繪制位置的x坐標(biāo)芦瘾。但是y是指文本繪制的baseline的y坐標(biāo)捌蚊。

以(0,0)為原點(diǎn)的繪制效果.png

具體測(cè)試代碼可參考Android 圖解Canvas drawText文字居中的那些事

要理解上圖中的繪制效果近弟,讓我們?cè)僬J(rèn)識(shí)下FontMetrics類缅糟,該類是Paint的內(nèi)部類。

/**
     * 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;
    }

在設(shè)置好字體尺寸后祷愉,通過(guò)Paint.getFontMetricsInt()方法來(lái)獲得一個(gè)FontMetrics對(duì)象窗宦。FontMetrics定義了幾個(gè)繪制時(shí)要用到的關(guān)鍵坐標(biāo)位置,各位置含義和圖示如下二鳄。注意赴涵,這四個(gè)字段的值是相對(duì)于baseline的相對(duì)值。

  • top值: 可繪制的最高高度y坐標(biāo) - baseline線y坐標(biāo)订讼,為負(fù)值
  • bottom值:可繪制的最低高度y坐標(biāo) - baseline線y坐標(biāo)髓窜,為正值
  • ascent值:系統(tǒng)建議的字符繪制最高高度y坐標(biāo) - baseline線y坐標(biāo),為負(fù)值
  • descent值:系統(tǒng)建議的字符繪制最低高度y坐標(biāo) - baseline線y坐標(biāo)欺殿,為正值


    FontMetrics標(biāo)線.png

baseline計(jì)算

場(chǎng)景1:給定文字繪制最高點(diǎn)的y值

即已知Top值寄纵,則baseline = top - fontMetrics.top.

場(chǎng)景2:給定文字繪制的中間線y值

1、已知a段(bottom和baseline之間距離)高度:a = fontMetrics.bottom
2脖苏、計(jì)算b段(bottom和中線的距離)高度:b = (fontMetrics.bottom - fontMetrics.top)/2
3程拭、計(jì)算c段(baseline和中線的距離)高度:c=b-a
4、計(jì)算baseline = centerY + c = centerY + b -a = centerY - (fontMetrics.bottom + fontMetrics.top) /2


image.png

實(shí)際計(jì)算時(shí)棍潘,也可以用decent和asent恃鞋,即baseline = centerY - (fontMetrics.ascent + fontMetrics.descent) /2

場(chǎng)景3:指定文字繪制的Rect

原理和場(chǎng)景2一致崖媚,此時(shí)centerY=(rect.bottom+rect.top)/2。
最終baseLine = (rect.bottom+rect.top)/2 - (fontMetrics.top + fontMetrics.bottom) /2

參考文檔:
Android 圖解Canvas drawText文字居中的那些事
drawText方法的baseline計(jì)算
Android Canvas drawText實(shí)現(xiàn)中文垂直居中

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末恤浪,一起剝皮案震驚了整個(gè)濱河市畅哑,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌资锰,老刑警劉巖敢课,帶你破解...
    沈念sama閱讀 219,188評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異绷杜,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)濒募,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,464評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門鞭盟,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人瑰剃,你說(shuō)我怎么就攤上這事齿诉。” “怎么了晌姚?”我有些...
    開(kāi)封第一講書(shū)人閱讀 165,562評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵粤剧,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我挥唠,道長(zhǎng)抵恋,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,893評(píng)論 1 295
  • 正文 為了忘掉前任宝磨,我火速辦了婚禮弧关,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘唤锉。我一直安慰自己世囊,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,917評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布窿祥。 她就那樣靜靜地躺著株憾,像睡著了一般。 火紅的嫁衣襯著肌膚如雪晒衩。 梳的紋絲不亂的頭發(fā)上嗤瞎,一...
    開(kāi)封第一講書(shū)人閱讀 51,708評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音浸遗,去河邊找鬼猫胁。 笑死,一個(gè)胖子當(dāng)著我的面吹牛跛锌,可吹牛的內(nèi)容都是我干的弃秆。 我是一名探鬼主播届惋,決...
    沈念sama閱讀 40,430評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼菠赚!你這毒婦竟也來(lái)了脑豹?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 39,342評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤衡查,失蹤者是張志新(化名)和其女友劉穎瘩欺,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體拌牲,經(jīng)...
    沈念sama閱讀 45,801評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡俱饿,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,976評(píng)論 3 337
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了塌忽。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片拍埠。...
    茶點(diǎn)故事閱讀 40,115評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖土居,靈堂內(nèi)的尸體忽然破棺而出枣购,到底是詐尸還是另有隱情,我是刑警寧澤擦耀,帶...
    沈念sama閱讀 35,804評(píng)論 5 346
  • 正文 年R本政府宣布棉圈,位于F島的核電站,受9級(jí)特大地震影響眷蜓,放射性物質(zhì)發(fā)生泄漏分瘾。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,458評(píng)論 3 331
  • 文/蒙蒙 一账磺、第九天 我趴在偏房一處隱蔽的房頂上張望芹敌。 院中可真熱鬧,春花似錦垮抗、人聲如沸氏捞。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,008評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)液茎。三九已至,卻和暖如春辞嗡,著一層夾襖步出監(jiān)牢的瞬間捆等,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,135評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工续室, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留栋烤,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,365評(píng)論 3 373
  • 正文 我出身青樓挺狰,卻偏偏與公主長(zhǎng)得像明郭,于是被迫代替她去往敵國(guó)和親买窟。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,055評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容