缘由
使用Canvas的drawText绘制文本是不会自动换行的,即使一个很长很长的字符串,drawText也只显示一行,超出部分被隐藏在屏幕之外。可以逐个计算每个字符的宽度,通过一定的算法将字符串分割成多个部分,然后分别调用drawText一部分一部分的显示, 但是这种显示效率会很低。
扩展
这里介绍下TextView的基本渲染原理,总的来说,TextView中负责渲染文字的主要是这三个类:
BoringLayout
主要负责显示单行文本,并提供了isBoring方法来判断是否满足单行文本的条件。
DynamicLayout
当文本为Spannable的时候,TextView就会使用它来负责文本的显示,在内部设置了SpanWatcher,当检测到span改变的时候,会进行reflow,重新计算布局。
StaticLayout
当文本为非单行文本,且非Spannable的时候,就会使用StaticLayout,内部并不会监听span的变化,因此效率上会比DynamicLayout高,只需一次布局的创建即可,但其实内部也能显示SpannableString,只是不能在span变化之后重新进行布局而已。
以上三个类都继承于Layout类,在此类中统一负责文本的具体绘制,在Layout.draw方法中,会对文本一行一行的进行渲染。
StaticLayout
StaticLayout是android中处理文字换行的一个工具类,StaticLayout已经实现了文本绘制换行处理,下面是如何使用StaticLayout的例子:
1 | package com.example.amdroidstaticlayoutdemo; |
这跟TextView的效果是一样的,其实TextView也是调用StaticLayout来实现换行的,StaticLayout的构造函数有三个:
1 | public StaticLayout(CharSequence source, |
- 需要分行的字符串
- 需要分行的字符串从第几的位置开始
- 需要分行的字符串到哪里结束
- 画笔对象
- layout的宽度,字符串超出宽度时自动换行
- layout的对其方式,有ALIGN_CENTER, ALIGN_NORMAL, ALIGN_OPPOSITE 三种
- 相对行间距,相对字体大小,1.5f表示行间距为1.5倍的字体高度。
- 在基础行距上添加多少
- 实际行间距等于这两者的和
- 参数未知
- 从什么位置开始省略
- 超过多少开始省略
需要指出的是这个layout是默认画在Canvas的(0,0)点的,如果需要调整位置只能在draw之前移Canvas的起始坐标
canvas.translate(x,y);