一、效果和思路
要实现如下效果

错误的思路:
1. 直接使用一个TextView设置背景即可。
2.使用SpannableString设置BackgroundColorSpan即可。
上面这两种思路都会产生中间没有白色的分割线,连成一起。这是因为用一个TextView设置背景的时候,背景的设置只会在TextView的边框区域产生作用。要实现以上效果,需要自定义一个。
二、字体度量
字体的度量,是指对于指定字号的某种字体,在度量方面的各种属性,其描述参数包括:
- baseline:字符基线
- ascent:字符最高点到baseline的推荐距离
- top:字符最高点到baseline的最大距离
- descent:字符最低点到baseline的推荐距离
- bottom:字符最低点到baseline的最大距离
- leading:行间距,即前一行的descent与下一行的ascent之间的距离

Paint.FontMetrics(Int)类,定义了字符的ascent、top、descent和bottom。
注意 :这几个属性值,是相对于baseline的坐标值,而不是距离值.
由上面的图我们可以得到以下几个结论:
- 字符的高度=descent++Math.abs(ascent);
- 字符的行高=字符的高度+行间距(也及leading)=Math.abs(ascent) + descent + leading=getLineHeight()
- 字符串的宽度=Paint.measureText(“xxxx”),字符串的宽高也可以通过Paint.getTextBounds()获得。
三、实现
了解以上知识,我们的思路是绘制高度为字符的高度,宽度为字符串的宽度的一个矩形背景即可。因此我们可以采用以下方式来实现:
一、自定义Span
这种方式实现LineBackgroundSpan接口主要实现drawBackground方法:
/**
* start 换行的起始位置
* end 换行的结束位置
* lineNumber 所在的行号
*/
void drawBackground(@NonNull Canvas canvas, @NonNull Paint paint,
@Px int left, @