Удалить весь ImageSpan, когда его часть удалена
Я пытаюсь реализовать Emoji в моем приложении, и я должен использовать короткие коды (например, :dog:
, :cat:
), а не юникод. У меня есть два устройства для тестирования и два разных поведения EditText
а также ImageSpan
в этом.
Первое: Meizu PRO 6, Android 6.0 (API 23)
Все работает как я хочу. Когда вы нажимаете клавишу Backspace на растянутом тексте, он полностью исчезает из EditText, потому что полностью растянутая часть строки была удалена.
Например, у вас есть "Привет :dog:
" в вашем EditText
(:dog:
заменяется изображением собаки), вы нажимаете клавишу Backspace, ваш EditText теперь содержит только "Hello ".
Второе: Google Pixel XL, Android 9.0 (API 28)
Когда вы нажимаете клавишу Backspace на растянутом тексте, вы просто удаляете :
символ, заставляющий рисунок остаться в EditText, потому что он не удаляет всю натянутую часть вашей строки. Но я хочу удалить это.
Что я попробовал
Я нашел этот код в другом вопросе здесь:
Android - Удалить весь ImageSpan, когда его часть удалена?
private val watcher = object : TextWatcher {
private var spanLength = -1
override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) {
if (start == 0) return
if (count > after) {
val spans =
editableText.getSpans(start + count, start + count, ImageSpan::class.java)
if (spans == null || spans.isEmpty()) return
for (i in spans.indices) {
val end = editableText.getSpanEnd(spans[i])
if (end != start + count) continue
val text = spans[i].source
spanLength = text!!.length - 1
editableText.removeSpan(spans[i])
}
}
}
override fun onTextChanged(s: CharSequence, start: Int, before: Int, after: Int) {
if (spanLength > -1) {
val length = spanLength
spanLength = -1
editableText.replace(start - length, start, "")
}
}
override fun afterTextChanged(s: Editable) {}
}
Он работает так, как задумано для Google Pixel XL, но полностью тормозит Meizu, удаляя 2-3 картинки или даже не натянутый текст, иногда выдает исключение, потому что start - length < 0
,
Есть ли способ решить это?
0 ответов
Я закончил с этим TextWatcher
private val watcher = object : TextWatcher {
private var spanLength = -1
private var spanStart = -1
override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) {
if (start == 0) return
if (count > after) {
val spans =
editableText.getSpans(start + count, start + count, EmojiSpan::class.java)
if (spans == null || spans.isEmpty()) return
for (i in spans.indices) {
val end = editableText.getSpanEnd(spans[i])
if (end != start + count) continue
val text = spans[i].getSource()
spanLength = text.length - 1
spanStart = editableText.getSpanStart(spans[i])
editableText.removeSpan(spans[i])
}
}
}
override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) {
if (spanLength > -1 && spanStart != -1 && count < before) {
val startSpan = spanStart
val endSpan = spanStart + spanLength
if (startSpan < 0 || endSpan > editableText.length) {
return
}
spanLength = -1
spanStart = -1
editableText.replace(startSpan, endSpan, "")
}
}
override fun afterTextChanged(s: Editable) {}
}
Похоже, это работает со всеми устройствами, которые я пробовал.