以上思路是借鉴 https://blog.csdn.net/wbwjx/article/details/66651931
Textview解析借鉴 https://blog.csdn.net/l_lhc/article/details/71105313
可以说是精简版 更加容易看懂实现原理
1.不同的是,删除文字块不需要再次选中才能删除,而是直接删除
先看整体效果图
下面是删除效果
下面是目录
下面三个方法开始是没有放在自定义view中,不过最好还是放在里面,方便管理
/**
* 把选中用户或话题 插入输入框
* @param insertData
*/
public void insertText(InsertData insertData) {
if (insertData == null) return;
String showText = insertData.showText();
String uploadFormatText = insertData.uploadFormatText();
int color = insertData.color();
Editable editable = getText();
int start = getSelectionStart();
int end = start + showText.length();
// 插入到指定位置
editable.insert(start, showText);
// 设置对应颜色
editable.setSpan(new ForegroundColorSpan(color), start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
// 保存文字块的起始位置+展示字符+发给后端的格式字符
FormatRangBean range = new FormatRangBean(start, end);
range.setUploadFormatText(uploadFormatText);
mRangeManager.add(range);
}
/**
* 每删除一个字符,都要遍历缓存队列,判断是否是删除了队列中的数据
* 如果删除是文字块前面的文字,对于后面的文字块要往前移位
* 如果是删除文字块,则把文字块在缓存列表删除后,对于后面的文字块要往前移位
* @param start
* @param end
* @param offset
*/
public void whenDelText(int start, int end,int offset){
Iterator iterator = mRangeManager.iterator();
while (iterator.hasNext()) {
RangBean rangBean = (RangBean) iterator.next();
// 判断起始位置是否包裹了文字块,如果包裹了,则把文字块相关信息在内存列表删除
if (rangBean.isWrapped(start, end)) {
iterator.remove();
continue;
}
// 将end之后的span,挪动offset个位置
if (rangBean.getFrom() >= end) {
rangBean.setOffset(offset);
}
}
}
/**
* 获取上传给服务端的格式化数据
* @return String
*/
public String getUploadFormatText() {
String text = getText().toString();
Collections.sort(mRangeManager);
int lastRangeTo = 0;
StringBuilder builder = new StringBuilder("");
String newChar;
for (FormatRangBean range : mRangeManager) {
builder.append(text.substring(lastRangeTo, range.getFrom()));
// 获取需要上传给后端的数据格式
newChar = range.getUploadFormatText();
builder.append(newChar);
lastRangeTo = range.getTo();
}
builder.append(text.substring(lastRangeTo));
return builder.toString();
}
遇到一个bug--23-6-12 (不知道为啥gif 动不了。。。)
如果插入的文字快是纯英文的时候,会有bug,如果光标在纯英文后面,会默认选中状态,研究了一下午,发现是系统的默认的,还没法去掉,太扯了
不得已 参考一下其他app的做法,只能在文字快后面 多加一个空格,如果是纯汉字则不需要加空格
其他代码就不贴出来了,具体可参考demo
gitee传送门 https://gitee.com/Pino_W/ait.git