Android Kotlin, создающий SpannableString из другого SpannableString, теряет диапазоны

Я работаю над созданием собственного MarkdownTextView.

В этом конкретном случае я просеиваю текст, анализируя пример тегов, выделенных курсивом:

Here is text, and *here is italic text*, and maybe *more* italic text

У меня есть функция регулярного выражения, которая выполняет отсеивание за меня:

(\*[^*])(.*?)([^*]\*)

Ниже приведен код, который я использую для замены всех фрагментов, выделенных курсивом:

val commentBody = "Here is text, and *here is italic text*, and maybe *more* italic text"
val check = "(\*[^*])(.*?)([^*]\*)".toRegex()
val newSpan = SpannableString(commentBody.replace(check, { result ->
    val innerSpan = SpannableString(result.value.substring(1, result.value.length - 1))
    innerSpan.setSpan(StyleSpan(Typeface.ITALIC), 0, innerSpan.length, spanFlag)
    return@replace innerSpan
}))

Мое регулярное выражение работает правильно, и

Here is text, and *here is italic text*, and maybe *more* italic text

правильно преобразуется для отображения

Here is text, and here is italic text, and maybe more italic text

Но ничего не выделено курсивом. Я отладил это, и это подтверждает мои опасения, что при установке диапазона курсива внутри этого преобразования и использовании его для настройки моей новой расширяемой строки я теряю все эти диапазоны.

Любые идеи?


person Josh Beckwith    schedule 18.02.2018    source источник
comment
Вы нашли хорошее решение для этого?   -  person Mark    schedule 31.07.2019


Ответы (2)


Если вы посмотрите на String.replace, вы Вы обнаружите, что SpannableString, которое вы возвращаете, на самом деле используется как CharSequence для transform: (MatchResult) -> CharSequence.

Также вы создаете внешний SpannableString только из чистого String.

Таким образом, у вас никогда не было доступной информации. Вы можете взглянуть на SpannableStringBuilder и использовать его с другим подходом, например с помощью токенизатора или пользовательского диапазона Markdown, который удаляет синтаксис разметки на лету.

person tynn    schedule 19.02.2018

Если кому интересно, мой ответ:

val commentBody = "Here is text, and *here is italic text*, and maybe *more* italic text"
val check = "(\\*[^*])(.*?)([^*]\\*)".toRegex()
val spannableStringBuilder = SpannableStringBuilder(commentBody.replace("*", ""))
check.findAll(commentBody).map { it.value.substring(1, it.value.length - 1) }.forEach { 
    val start = spannableStringBuilder.indexOf(it)
    val end = start + it.length
    spannableStringBuilder.setSpan(StyleSpan(Typeface.ITALIC), 0, innerSpan.length, spanFlag)
}
return spannableStringBuilder
person Edy Daoud    schedule 12.11.2018