Android 删除或者修改部分文本的span标签

最近在编写一个日志APP,要求对EditText里的文本进行实时的文本编辑和格式编辑(加粗、下划线、颜色、字号等),以及能够实现撤销和重做,我使用了操作队列和控制指针来完成这件事。有必要记录一下整个过程中遇到的问题。

一、Span的部分修改
首先看下面四种情况,代表了同一个字符串上加载了不同数量的加粗span,也就是StyleSpan(Typeface.BOLD)。

0123456789
0123456789
0123456789
0123456789

在文本编辑器中,假如我们此时选中了子字符串“3456”,并且按下加粗按钮B,那么理论上上述字符串应该变为:

0123456789
0123456789
0123456789
0123456789

那么在代码层面,我们要怎么实现这样的部分操作呢?

我们注意到,这个操作实际上涉及到了区间内所有span标签的修改、融合或者删除,那么从编程的角度上讲,可以用下面的删除-重新绘制思路:

  1. 获取区间[start, stop]内所有对应类别(例如这里是加粗)的span标签
  2. 记录最左标签的起点oStart和最右标签的终点oStop(也就是span标签的最小起点和最大终点)
  3. 删除所有span标签
  4. 判断左边界和右边界的格式是否与区间内新的格式相同,如果左边界相同,那么start更新为oStart,如果右边界相同,那么stop更新为oStop (中span扩展)
  5. 在区间[start, stop]内绘制span标签
  6. 如果(start!=oStart)那么在在区间[oStart, start]内绘制span标签,如果(stop!=oStop)那么在区间[stop, oStop]内绘制span标签
  7. 结束更新
SpannableStringBuilder spanText; //待修改的对象
int newType; //待添加的格式

int oStart = start;
int oStop = stop;
int leftType;
int rightType;
StyleSpan[] T = spanText.getSpans(start, stop, StyleSpan.class); //获取区间内所有的加粗span对象
for (int i=T.length-1; i>=0; i--) {
	if (spanText.getSpanStart(T[i]) < oStart){
		oStart = spanText.getSpanStart(T[i]);
		leftType = T[i].getStyle();
	}
	if (spanText.getSpanEnd(T[i]) > oStop) {
		oStop = spanText.getSpanEnd(T[i]);
		rightType = T[i].getStyle();
	}
	spanText.removeSpan(T[i]); 
	//移除这些对象,注意,这里i是从大到小变化
}
if (leftType==newType) start = oStart;
else if (leftType!=0) spanText.setSpan(new StyleSpan(leftType), oStart, start, Spanned.SPAN_EXCLUSIVE_INCLUSIVE);//绘制左span
if (rightType==newType) stop = oStop;
else if (rightType!=0) spanText.setSpan(new StyleSpan(rightType), stop, oStop, Spanned.SPAN_EXCLUSIVE_INCLUSIVE);//绘制右span
if (newType!=0) spanText.setSpan(new StyleSpan(newType), start, stop, Spanned.SPAN_EXCLUSIVE_INCLUSIVE);//绘制中span

结果就不展示了,带加粗的文本编辑器到处都是。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值