Використання HTML в віджеті Text в Android Jetpack Compose

pic

У розробці для Android, HTML з'являється як Spannable, і компонент Compose Text не може прийняти Spannable як значення. Якщо ви хочете передати HTML текст як значення для компонента Text, ви можете написати розширення для Kotlin, щоб перетворити Spanned на AnnotatedString, як показано нижче.

fun Spanned.toAnnotatedString(): AnnotatedString = buildAnnotatedString {  
 val spanned = this@toAnnotatedString  
 append(spanned.toString())  
 getSpans(0, spanned.length, Any::class.java).forEach { span ->  
 val start = getSpanStart(span)  
 val end = getSpanEnd(span)  
 when (span) {  
 is StyleSpan -> when (span.style) {  
 Typeface.BOLD -> addStyle(SpanStyle(fontWeight = FontWeight.Bold), start, end)  
 Typeface.ITALIC -> addStyle(SpanStyle(fontStyle = FontStyle.Italic), start, end)  
 Typeface.BOLD_ITALIC ->  
 addStyle(  
 SpanStyle(fontWeight = FontWeight.Bold, fontStyle = FontStyle.Italic),  
 start,  
 end  
 )  
 }  

 is UnderlineSpan -> addStyle(  
 SpanStyle(textDecoration = TextDecoration.Underline),  
 start,  
 end  
 )  

 is ForegroundColorSpan -> addStyle(  
 SpanStyle(color = Color(span.foregroundColor)),  
 start,  
 end  
 )  
 }  
 }  
}

Ця функція розширення для класу Spanned створює еквівалент AnnotatedString, переносячи стилі та їх відповідні відрізки з Spanned у SpanStyle Compose і додаючи їх до AnnotatedString.

Детальне пояснення

Параметри

  • Функція є розширенням класу Spanned, тому об'єкт Spanned, що перетворюється, доступний як this@toAnnotatedString.

Значення, що повертається

  • Повертається AnnotatedString, побудований за допомогою DSL Compose buildAnnotatedString.

Кроки реалізації

  1. Ініціалізація Builder:
buildAnnotatedString {  
 ...  
}

Ініціалізується builder для AnnotatedString. Це надає DSL для додавання тексту та застосування стилів.

2. Додати текст:

append(spanned.toString())

Звичайний текст з об'єкта Spanned витягується та додається до AnnotatedString.

3. Ітерація по відрізках:

getSpans(0, spanned.length, Any::class.java).forEach { span -> }
  • Усі відрізки в об'єкті Spanned отримуються за допомогою getSpans.
  • Ці відрізки визначають ділянки тексту з певними стилями.
  • Ділянки кожного відрізка визначаються за допомогою getSpanStart(span) і getSpanEnd(span).

4. Обробка різних типів відрізків: Кожен тип відрізка співвідноситься з відповідним SpanStyle в Compose:

  • StyleSpan:
  • Представляє стиль тексту, такий як жирний, курсив або жирний-курсив.
  • Відображається за допомогою fontWeight та fontStyle в SpanStyle.
is StyleSpan -> when (span.style) {  
 Typeface.BOLD -> addStyle(SpanStyle(fontWeight = FontWeight.Bold), start, end)  
 Typeface.ITALIC -> addStyle(SpanStyle(fontStyle = FontStyle.Italic), start, end)  
 Typeface.BOLD_ITALIC -> addStyle(  
 SpanStyle(fontWeight = FontWeight.Bold, fontStyle = FontStyle.Italic), start, end  
 )  
}
  • UnderlineSpan:
  • Представляє підкреслений текст.
  • Відображається за допомогою textDecoration = TextDecoration.Underline.
is UnderlineSpan -> addStyle(  
 SpanStyle(textDecoration = TextDecoration.Underline),  
 start,  
 end  
)
  • ForegroundColorSpan:
  • Представляє текст з певним кольором переднього плану.
  • Відображається за допомогою color = Color(span.foregroundColor).
is ForegroundColorSpan -> addStyle(  
 SpanStyle(color = Color(span.foregroundColor)),  
 start,  
 end  
)

5.
Застосування стилів до ділянок:** Для кожного типу відрізка відповідний SpanStyle застосовується до тексту в межах ділянки відрізка [start, end).

Поведінка коду

  • Перетворює всі підтримувані типи відрізків (StyleSpan, UnderlineSpan, ForegroundColorSpan) на їх еквіваленти в Compose.
  • Забезпечує збереження форматування та вигляду стильованого тексту, визначеного в оригінальному об'єкті Spanned.
val htmlText = """  

This is bold text and this is italic text.
You can even combine both styles!
    """.trimIndent()      
val htmlSpannableText = HtmlCompat.fromHtml(htmlText, HtmlCompat.FROM_HTML_MODE_LEGACY)   
val annotatedString = spannedText.toAnnotatedString()   
Text(annotatedString) 




Перекладено з: [Using html in Android Jetpack Compose Text widget](https://medium.com/@ali.alireza8002/using-html-in-android-jetpack-compose-text-widget-aa8166bfbf84)

Leave a Reply

Your email address will not be published. Required fields are marked *