Canvas drawText文字垂直居中方案

最近繪制自定義view時(shí),用到畫筆繪制文本,針對(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è)置好字體尺寸后,通過Paint.getFontMetricsInt()方法來獲得一個(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)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

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