Как работает механизм отображения HTML-текста в Android TextView
Что проверяют
Знаете ли вы, что TextView не рендерит HTML, а показывает размеченный текст из спанов, и понимаете ли, какие теги переживут конвертацию. Следом обычно спрашивают, почему не кликаются ссылки и как вывести HTML из строковых ресурсов с подстановкой аргументов.
Как отвечать
Html.fromHtml(source, flags) разбирает строку встроенным парсером и собирает Spanned, по сути SpannableStringBuilder со спанами:
- начертание:
<b>,<strong>,<i>,<em>даютStyleSpan,<u>даётUnderlineSpan,<s>и<del>даютStrikethroughSpan; - ссылки:
<a href>превращается вURLSpan; - размер и цвет: заголовки от
<h1>до<h6>даютRelativeSizeSpan, атрибутcolorу<font>и цвет в простом атрибутеstyleдаютForegroundColorSpan; - блоки:
<p>,<div>,<br>,<blockquote>,<li>превращаются в переводы строк,QuoteSpanиBulletSpan.
Флаг FROM_HTML_MODE_LEGACY разделяет блоки двумя переводами строки, FROM_HTML_MODE_COMPACT одним. Версия без флагов устарела с API 24, а на практике берут HtmlCompat.fromHtml() из androidx.core или расширение parseAsHtml() из core-ktx.
Чего нет: таблиц, CSS-классов, скриптов. Картинки <img> грузятся только через Html.ImageGetter, свои теги обрабатываются через Html.TagHandler. Ссылки становятся кликабельными лишь после textView.movementMethod = LinkMovementMethod.getInstance(). Для полноценной вёрстки нужен WebView, а в Compose есть AnnotatedString.fromHtml().
Про безопасность: JavaScript в TextView не выполняется, поэтому классического XSS нет. Реальный риск в ссылках: URLSpan из недоверенного HTML откроет любую схему, включая диплинки в другие приложения. Пользовательские аргументы экранируйте через TextUtils.htmlEncode().
Где спотыкаются
Берут HTML из strings.xml через getString(): он выбрасывает разметку. Для простых тегов подходит getText(), а для строки с аргументами нужен CDATA или экранирование и затем fromHtml.
Забывают про LinkMovementMethod и ищут, почему ссылка подчёркнута, но не нажимается.
Парсят HTML в onBindViewHolder на каждую прокрутку. Разбор не бесплатный, Spanned лучше готовить заранее.