需求:
- 当文字超过限定行数时,需要在文字末尾显示“…全文”;
- 解决行末标点换行,和英文换行问题;
- 文字分块,包含多种颜色,多种点击事件(单独这个需求可以使用Spannable解决);
准备工作:
先在网上查了一遍,需求1、2都没有找到相关Api解决,需要自定义去测量、计算、绘制文字;
解决思路大致如下:
- 测量计算每一行要显示的内容(一行内可能包含多个小块,多种颜色,多个点击事件);
- 控制画布画笔绘制文字;
- 根据点击范围,分发点击事件
大致的计算过程:
- 将需要绘制的文字分成多个小块(TagTextItem),每一小块需要一个唯一id(用于后面的点击分配),样式信息(详细见TagTextStyle),保存在一个列表中;
- 遍历1中的列表,测量并创建绘制信息列表(TagTextPieceInfo);
- 使用Paint.class中measureText(String text, int start, int end)方法测量,end从start+1开始,如果剩余空间充足就使end+1知道块内文字全部测量;不足就将上一次的测量记录保存在TagTextPieceInfo中,并且行数加1;
- 遇到'\n'字节时,记录上一次的测量记录,行数加1;
- 如果设置的最大行数(maxLines),则最后一行的空间需要剪掉文末提示文案宽度,文字无法全部显示时绘制文末提示文案;
优化:
- TagTextPieceInfo复用(TagTextRecycler);
- 使用Delegate逻辑与视图分离(TagTextDelegate);
- 支持行高设定(低版本Android SDK只支持lineSpace,UI调起来很费劲),支持滚动,支持段落间隔设定;
下一步(尚未实现部分):
- 测量的算法优化,现在都是每次增加1个去测量的,想找到一个可以一次增加多个再测量的方案,可以减少测量次数;
- 未实现EditText;
代码传送(比较长):
源码地址:https://github.com/FirstLetterZ/Dependence/blob/master/views/src/main/java/com/zpf/views/tagtext
Gradle依赖: com.zpf.android:tool-views:0.0.8 (持续更新中)
2020-09-29
网友评论