Android - Применение нового StyleSpan удаляет ранее примененные промежутки - PullRequest
1 голос
/ 10 апреля 2020

Я создаю приложение, которому требуются такие функции форматирования текста, как выделение выделенного текста жирным шрифтом, Itali c, перечеркнутый, подчеркивание и т. Д. c. Я использовал StyleSpan (Typeface.BOLD), StyleSpan (Typeface.Itali c), 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)
 }

Первоначально у меня было следующее форматирование Formatting With Bold and Strike Through Затем я выделил весь текст и применил Bold. Он должен был показать все жирным шрифтом вместе с Strike Through из предыдущего форматирования, но этого не произошло. Вот что происходит: Text gets Bold, but Strike Through gets removed.

Ответы [ 2 ]

1 голос
/ 11 апреля 2020

Проблема заключалась в использовании 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)
    }
}

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

0 голосов
/ 10 апреля 2020
        val selectedText: String = mEditTextNoteContent.text.toString().substring(selectionStart, selectionEnd)

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

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

        val selectedText: CharSequence = TextUtils.substring(mEditTextNoteContent.text, selectionStart, selectionEnd)
...