前言:
在自定义控件中,有时我们也需要在其中加入一些文本进行绘制时,那么,此时,对于文本绘制的位置,
我们就必须做到心中有数,下面就来聊一下其文本尺寸的相关知识点:
文本宽度的获取
方式一:
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()
文本的真实高度,可通过如下方式来获取:
Rect rect = new Rect(); paint.getTextBounds(text,0,text.length(), rect); height = rect.height()
若通过如下方式获取宽度:
width = paint.measureText(text,0,text.length());则用这个宽度当做文本绘制的宽度,则可以使绘制的控件和文本之间留有一丝间隙,
看起来更具美感
4>
FontMetricsInt类的几个属性提供给我们,主要是方便我们在绘制期间更好地计算文本和控件之间的距离,
同时也让文本和绘制的控件更具美感(因为有一定间隙)。至于说,top和ascent之间如何选择,主要是看
个人需求,如果觉得用ascent有些紧凑,那你可以选择更大一点空间的top值,bottom和descent之间的
选择也是如此
源码:
关注微信公众号获取更多资讯