Удалить весь ImageSpan, когда его часть удалена - PullRequest
0 голосов
/ 23 октября 2018

Я пытаюсь реализовать Emoji в своем приложении, и я должен использовать короткие коды (например, :dog:, :cat:), а не юникод.У меня есть два устройства для тестирования и два различных поведения EditText и ImageSpan в нем.

Первое: Meizu PRO 6, Android 6.0 (API 23)

Все работает, как я хочу.Когда вы нажимаете клавишу Backspace на растянутом тексте, он полностью исчезает из EditText, потому что была удалена полностью растянутая часть строки.

Например, у вас есть «Hello :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.

Есть ли способ решить эту проблему?

1 Ответ

0 голосов
/ 14 июня 2019

Я закончил с этим 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) {}
}

Похоже, он работает на всех устройствах, которые я пробовал.

...