Android中关于字体宽高的获取

本文详细介绍了在Android中如何获取文本的宽度和高度,包括两种获取宽度的方法及其区别,以及如何利用FontMetricsInt类计算文本高度。文章强调了在实际应用中根据需求选择适当方法的重要性,并提供了源码示例。

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

前言:

在自定义控件中,有时我们也需要在其中加入一些文本进行绘制时,那么,此时,对于文本绘制的位置,

我们就必须做到心中有数,下面就来聊一下其文本尺寸的相关知识点:


文本宽度的获取

方式一:

width = paint.measureText(text,0,text.length());

方式二:

Rect rect = new Rect();
paint.getTextBounds(text,0,text.length(), rect);
width = rect.width();

那么,android系统给我们提供这两种方式去获取干嘛呢?用一种不就好了,

能这么想,很有计算机的天赋,我当时也是这么想的,后来实验了一把,

第一种方式,得到的width获取第二种方式得到的width的值会大一点,

这又是为什么呢?第一种方式得到的width会在左右文本留有一丝间距,

这样在与其它控件并排绘制时,会有一种美感,第二种方式得到的就是

文本的真正宽度,两边刚好紧密包裹着文本,两种宽度,具体使用哪一种,

看用户自己的一个需求,如果想绘制的控件和文本并排时留有一点空隙,

就推荐使用第一种,想绘制的控件和文本之间不留任何空隙,那就使用第二种方式


文本高度的获取

在得出文本高度获取之前(卖下关子 ^_^),我们先来熟悉一下FontMetricsInt这个类的几个属性:

在谷歌文档中,关于这几个属性的解释具体如下:



通过上述解释,我们可以大概知道一些信息:

ascent和top是位于位于Baseline之上的,descent和bottom是位于Baseline之下的。

那么,问题来了,Baseline是个什么鬼?Baseline就是我们在绘制文本去调用

canvas.drawText()时,其参数中所指定的坐标就是Baseline这条线的一个起始坐标。

然后,还可以得到一点信息就是:

ascent是基于Baseline之上,一个推荐的间距值

bottom是基于Baseline之下,一个最大的间距值

descent是基于Baseline之下,一个推荐的间距值

leading就是文本的行与行之间的一个间距值

top是基于Baseline之上,最大的一个间距值

看了上述解释,我看大家还晕乎乎的,现在用如下一个图来解释一下:


这几个属性都可通过如下式子得到其值:

leading = paint.getFontMetrics().leading;
top = paint.getFontMetrics().top;
ascent = paint.getFontMetrics().ascent;
descent = paint.getFontMetrics().descent;
bottom = paint.getFontMetrics().bottom;

从上述示意图中,我们看到:

还是没法确切得到文本的高度,因为其与文本之间还是留有一些空隙,

并不能确切知道文本具体的一个高度值,你能看到这一点,就说明很

有前途,至少在计算机这条路上我没有看错你。那么,既然这几个属性

没法解决我们的问题,那么Android小弟必须给我们提供其它的API,是不?

那就是通过paint.getTextBounds(....)这个方法会返回Rect,然后调用Rect.height()

得到一个高度值,那么此时这个高度值就是紧紧包裹文本的高度值,其与文本是

紧紧贴在一起的。也就是说,我们通过Rect.height()就可以得到文本的一个具体

的高度值。


那么,问题又来了,说了这么多,直接告诉我们Rect.height()得到其高度值不就

可以了么?还介绍啥FontMetricsInt类的属性,主要是因为,在文本绘制的过程中,

文本是基于一条Baseline来进行绘制的,而Baseline一般不是完全处于文本的下方

的,而是处在文本中间偏下的一个位置,这样,就算给出了文本的高度,也知道

Baseline具体位置,还是不方便直接得出文本距离Baseline上边有多少间距,

距离Baseline下边有多少间距,所以,我想这大概就是Android给我们引出FontMetricsInt

类的几个属性的原因,有了FontMetricsInt这个类的几个属性之后,我们在文本的

上下方去绘制其它控件时,就可以很清晰地知道在距离Baseline的下方多少距离时去绘制

就可以刚好不用覆盖文本了



总结:

1>

文本的真实宽度,可通过如下方式来获取:

Rect rect = new Rect();
paint.getTextBounds(text,0,text.length(), rect);
width = rect.width()


2>

文本的真实高度,可通过如下方式来获取:

Rect rect = new Rect();
paint.getTextBounds(text,0,text.length(), rect);
height = rect.height()


3>

若通过如下方式获取宽度:

width = paint.measureText(text,0,text.length());
则用这个宽度当做文本绘制的宽度,则可以使绘制的控件和文本之间留有一丝间隙,

看起来更具美感


4>

FontMetricsInt类的几个属性提供给我们,主要是方便我们在绘制期间更好地计算文本和控件之间的距离,

同时也让文本和绘制的控件更具美感(因为有一定间隙)。至于说,top和ascent之间如何选择,主要是看

个人需求,如果觉得用ascent有些紧凑,那你可以选择更大一点空间的top值,bottom和descent之间的

选择也是如此


源码:

字体宽高获取的示例源码



关注微信公众号获取更多资讯


评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值