Android - применение нового StyleSpan удаляет ранее примененные диапазоны

Я создаю приложение, для которого требуются такие функции форматирования текста, как выделение выделенного текста жирным шрифтом, курсивом, зачеркиванием, подчеркиванием и т. Д. Я использовал StyleSpan(Typeface.BOLD), StyleSpan(Typeface.Italic), UnderlineSpan(), StrikethroughSpan() предоставляется android. Все они работают нормально. Но когда я пытаюсь применить новый диапазон к предыдущему диапазону, ранее примененный диапазон удаляется и применяется новый. Вот функция, которую я использую для применения формата на основе нажатия кнопки:

  fun formatText(typefaceCode: StyleSpan = StyleSpan(Typeface.BOLD), isUnderline : Boolean = false, isStrikeThrough : Boolean = false, isQuote : Boolean = false){
            val selectionStart: Int = mEditTextNoteContent.selectionStart
            val selectionEnd: Int = mEditTextNoteContent.selectionEnd
            val selectedText: String = mEditTextNoteContent.text.toString().substring(selectionStart, selectionEnd)
            val formattedString = SpannableStringBuilder(selectedText)
            when {
                isUnderline -> formattedString.setSpan(UnderlineSpan(), 0, selectedText.length, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
                isStrikeThrough -> formattedString.setSpan(StrikethroughSpan(), 0, selectedText.length, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
                isQuote -> mEditTextNoteContent.text.replace(selectionStart, selectionEnd,  "\"" + selectedText + "\"")
                else -> formattedString.setSpan(typefaceCode, 0, selectedText.length, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
            }
            if(!isQuote)
                mEditTextNoteContent.text.replace(selectionStart, selectionEnd, formattedString)
 }

Изначально у меня было следующее форматирование. Затем я выделил весь текст и применил полужирный шрифт. Он должен был показать все жирным шрифтом вместе с зачеркиванием из предыдущего форматирования, но этого не происходит. Вот что происходит:

2 ответа

Проблема заключалась в использовании replace() в EditText. Вместо использования replace() вы должны использовать метод editText.setSpan().

Таким образом, обновленный Код выглядит так:

fun formatText(typefaceCode: StyleSpan = StyleSpan(Typeface.BOLD), isUnderline : Boolean = false, isStrikeThrough : Boolean = false, isQuote : Boolean = false, isBulletSpan : Boolean = false){
    val selectionStart: Int = mEditTextNoteContent.selectionStart
    val selectionEnd: Int = mEditTextNoteContent.selectionEnd
    val selectedText: CharSequence = TextUtils.substring(mEditTextNoteContent.text, selectionStart, selectionEnd)
    when{
        isUnderline -> mEditTextNoteContent.text.setSpan(UnderlineSpan(), selectionStart, selectionEnd, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
        isStrikeThrough -> mEditTextNoteContent.text.setSpan(StrikethroughSpan(), selectionStart, selectionEnd, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
        isQuote -> mEditTextNoteContent.text.replace(selectionStart, selectionEnd,  "\"" + selectedText + "\"")
        else -> mEditTextNoteContent.text.setSpan(typefaceCode, selectionStart, selectionEnd, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
    }
}

Это не перезапишет ранее использованные промежутки.

        val selectedText: String = mEditTextNoteContent.text.toString().substring(selectionStart, selectionEnd)

toString() стирает промежутки, так как вы специально просите его переключиться на String от CharSequence.

Использовать TextUtils.substring() работать напрямую с CharSequence. Вероятно, это приведет к чему-то вроде:

        val selectedText: CharSequence = TextUtils.substring(mEditTextNoteContent.text, selectionStart, selectionEnd)
Другие вопросы по тегам