android drawtext参数,Android中canvas中drawText详解

本文详细探讨了Android中Canvas的drawText方法,解释了基线的概念,以及如何在Android中计算基线。通过分析getTextBounds和getFontMetrics方法,提供了计算基线的代码示例,帮助理解并正确绘制文字。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

开篇

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

1.为什么会有基线?

汉字字母数字不在一个水平线上,g的底部跟h的底部不在同一水平线上(看下图)

2fde2f7fba20

image

在绘制汉字的时候并不是从底部(蓝色线)开始绘制,而是以图中红色的线绘制文字。

2.安卓中如何计算基线

首先,我们都知道我们安卓屏幕的坐标系是右下坐标系,即x轴朝右越来越大,y轴朝下越来越大。知道这个,我们先看下官方提供的api:

/**

* 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)

这里要说明的是,这里的drawText中x跟y坐标系都是相对于自定义控件本身矩形框,这边我们主要要关注的就是第三个参数,就是我们今天要讨论的水平基线,从官方解释看,就是在绘制文字时候的沿y轴的基线,在看看第二个参数,官方给出的解释中并没有提基线(baseLine),即是从最初始的位置,即文字最左边开始绘制,这符合我们日常认知。

现在可能对基线还不是很明白,再往下看这张图(来源于其他博客)

2fde2f7fba20

先解释下图中提供的红的边框,来自于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;

}

我们该利用现有的如何计算基线呢?既然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.jianshu.com/u/35083fcb7747

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值