删除整个ImageSpan的一部分时,将其删除 [英] Delete entire ImageSpan when the part of it is deleted
问题描述
我正在尝试在我的应用程序中实现Emoji,我应该使用短代码(例如:dog:
,:cat:
),而不是unicode.我有两个要测试的设备以及其中的EditText
和ImageSpan
两种不同行为.
I'm trying to implement Emoji's in my app and I should use short codes (like :dog:
, :cat:
), not unicode. I have two devices to test on and two different behaviours of EditText
and ImageSpan
in it.
首先:魅族PRO 6,Android 6.0(API 23)
一切正常.在跨度文本上点击退格键时,它会从EditText中完全消失,因为已删除了字符串的全跨度部分.
Everything works as I want. When you tap backspace on the spanned text, it disappears from EditText completely, because full spanned part of the string was removed.
例如,您在EditText
中有一个"Hello :dog:
"(:dog:
替换为狗的图片),按Backspace键,您的EditText现在仅包含"Hello".
For example, you have a "Hello :dog:
" in your EditText
(:dog:
is replaced with a picture of the dog), you press backspace, your EditText contains only "Hello " now.
第二个:Google Pixel XL,Android 9.0(API 28)
在跨度文本上点击退格键时,只需删除:
符号,使图片停留在EditText中,因为它不会删除字符串的所有跨度部分.但是我要删除它.
When you tap backspace on the spanned text, you just remove the :
symbol, making picture stay in EditText because it doesn't remove all spanned part of your string. But I want to remove it.
我尝试了什么
我在这里的另一个问题中找到了此代码:
I found this code in the other question here:
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,但完全阻止了魅族删除2-3张图片或什至没有跨文本的内容,有时会由于start - length < 0
而引发异常.
It works as intended for Google Pixel XL, but completely brakes Meizu removing 2-3 pictures or even not spanned text, sometimes it throws an Exception because start - length < 0
.
有什么办法解决这个问题?
Is there any way to solve this?
推荐答案
我最终得到了这个TextWatcher
I ended up with this 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) {}
}
它似乎可以在我尝试过的所有设备上使用.
Looks like it works with all devices I've tried.
这篇关于删除整个ImageSpan的一部分时,将其删除的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!