安卓开发

Android中canvas中drawText详解

2020-11-03  本文已影响0人  TongFly

开篇

安卓写自定义View中有一个类相信大家不会陌生,那就是Canvas。Canvas给我们调用者提供的api也很丰富。我们经常用到的画圆(drawCircle),画线(drawLine)。今天我们的要看的问题,是drawText(文字)。为什么要单独说画文字,因为安卓的drawText中,基线问题常常困扰我们,到底该怎么计算基线?正题开始:

1.为什么会有基线?

2.安卓中如何计算基线

/**
     * 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)
    
   
  1. 先解释下图中提供的红的边框,来自于Paint(画笔)中getTextBounds方法,即获取文字的矩形区域,这要注意的是,坐标系(重点),获取到的top,left,bottom,rightt都是根据基线跟左边框相交的点为原点的(忽略padding),假设文字宽100px,高20px,同时假设基线距离文字宽的一半位置为3px,则top=-(20/2+3)=-13px,bottom=(20/2-3)=7px,left=0px,right=100px;
    /**
     * Retrieve the text boundary box and store to bounds.
     *
     * 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 to 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) {

2.再看图蓝色矩形框,来自于Paint中getFontMetrics方法中,大致意思是获取该字体的相关参数,参照api29文档 大致意思是,ascent 是单行字符距离基线的顶部最打值,top是所有字符距离基线的最高值,descent 是单行字符距离基线的底部最大值,bottom是所有字符距离基线的顶部最大值。

 /**
     * 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;
    }
  1. 我们该利用现有的如何计算基线呢?既然drawText 是根据图中星星位置开始绘制,先算出基线与文字矩形框中线高度的差值(这里是正值),差值+控件高度的一半,即是基线的y坐标。话不多说,上代码
        //先用画笔测量文字
        paint.getTextBounds(text, 0, text.length() - 1, bounds);
        //获取 FontMetrics对象
        Paint.FontMetrics fontMetrics = paint.getFontMetrics();
        // 计算中线跟基线的差值
        float dy = (fontMetrics.bottom - fontMetrics.top) / 2 - fontMetrics.bottom;
        //计算baseLineY
        float baseLineY = getHeight() / 2 + dy;
    

如有错误,欢迎私聊指正,此博客本人根据B站视频中自己总结的,原创视频出处:https://www.bilibili.com/video/BV15K411L7gU?t=630&p=16

上一篇 下一篇

猜你喜欢

热点阅读