input.png
以上思路是借鑒 https://blog.csdn.net/wbwjx/article/details/66651931
Textview解析借鑒 https://blog.csdn.net/l_lhc/article/details/71105313
可以說是精簡版 更加容易看懂實現原理
1.不同的是,刪除文字塊不需要再次選中才能刪除,而是直接刪除
先看整體效果圖
a1.gif
下面是刪除效果
a2.gif
下面是目錄
a3.png
下面三個方法開始是沒有放在自定義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 動不了。。。)
空格.gif
如果插入的文字快是純英文的時候,會有bug,如果光標在純英文后面,會默認選中狀態,研究了一下午,發現是系統的默認的,還沒法去掉,太扯了
image.png
不得已 參考一下其他app的做法,只能在文字快后面 多加一個空格,如果是純漢字則不需要加空格
image.png
其他代碼就不貼出來了,具體可參考demo
gitee傳送門 https://gitee.com/Pino_W/ait.git