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)