需求
自适应大小的文本:
效果图:
项目开发中,开发人员根据UI人员提供的一套尺寸,布局了一些带文本的页面,
往往会少考虑一些数据极限的问题,造成机型屏幕问题。
例如:
文本(或数值)长度可变,如经验值、金币数量等,如果页面同一高度使用了多个Textview布局摆放,当Textview文本长度增加时,有可能造成重叠现象。
例子还有很多,相信很多开发人员也都曾遇到过。
今天我们就写一个简单的例子,解决该问题。
我们项目中的实际需求:
1\. 文本控件单行、居中显示;
2\. 文本控件默认有一个固定尺寸,如果文本过多,字号自动变小,文本仍然完全显示,不折行;
3\. 文本控件尺寸变小,文本不变,字号也自动变小,文本仍然完全显示,不折行;
其实2和3仔细分析一下是一个意思:
文本控件的空间不够存放当前文本时,字号自动缩小。
分析
一般的情况,很多开发者做法是继承TextView,控制其属性以达到效果。
我们换一种做法。
TextView文本说到底,就是一个View,而我们看到的文本,其实是通过画笔绘制在View空间(即:画布)上的。
那么我们也使用这种方式,画笔来实现吧。
可能有开发者会担心很难,其实一点也不难,只需要简单掌握几个基础知识(1. 画布、2. 画笔、3. 文本绘制的计算)就可以了。
我们自定义出来的控件代码,不会比直接继承TextView多,而且大家还能学到更多有用的知识。
那么我们开始分析:
如何在一定的空间中自适应文本的大小,使其能完全显示?
原理很简单,就是把字号变小就行了,那么变成多小?如何计算呢?
1. 我们要实现的控件,只是一个文本显示,界面不复杂,所以我们不需要使用XML,只写一个自定义类即可;
2. 自定义类直接继承View;
3. View中可获得的或者外界传入的信息(即:已知条件):
3.1 文本信息Text(外界传入)
3.2 字号最大值MaxSize(外界传入, 即,我们设置的默认字号,因为字号只会缩小,不会增加,所以也叫字号最大值)
3.3 文本使用字号最大值应显示的宽度PreWidth(可通过Paint、Text、MaxSize获得)
3.4 空间的宽度canvasWidth(即画布宽度,可在View的onSizeChanged方法中获得);
那么,当空间不足以显示文本时,应通过已知条件计算canvasWidth应对应的字号大小 X,
如何计算呢?
经过分析,大字体显示的宽度与小字体显示的宽度比值应是一致的,所以,公式如下:
MaxSize / PreWidth = x / canvasWidth;
x = MaxSize * canvasWidth / PreWidth;
x 就是我们需要重新设置的字号。
得到字号,我们就可以为画笔设置文字大小了,也就可以通过画笔画出合适大小的文字了。
4. 绘制文本,文本的坐标如何处理呢?
此处我们以居中显示为例:
我们可以通过文本宽高与画布宽高可计算出文字应被绘制的位置(x,y)
例如:
容器(即画布)宽10,高10,文字宽4,高4,我们把容器和文字分别想象成两个矩形,
如何使文字矩形居中显示在容器矩形里,需要我们算出文字矩形左上角的位置(x,y),即文字绘制的位置,
其实也很简单: