【備考】
HTMLCompatというクラスを使用してHTML文字列の部分だけ文字色を変える方法を学んだため記録として残します。
漏れや不備等があるかもしれないため、その点ご理解いただけますと幸いです
やりたいこと
ざっくり手順
① HTML文字列の準備する
② 再利用できるようにHTML形式の文字列を表示するためのComposable関数を作成する
③ 作成したComposable関数を必要な場所で呼び出して表示する
① HTML文字列の準備
HTML形式(例えば タグで部分的に文字色を変えるなど)を使った文字列を用意します。
▼例
"ご覧いただきありがとうございます。HTML形式のテキストを<font color='#ed293e'>一部赤色の文字で表示します。</font>"
② Composable関数を作成
HTML形式の文字列を表示するためにComposable関数を作成します。
補足として、再利用しやすい命名にすると良さそうです。
以下細かな手順です。
1. HTMLCompatを使ってHTMLを変換する
HtmlCompat.fromHtml
を使用して、HTML文字列を変換し、spanned
という変数に格納します。
val spanned = HtmlCompat.fromHtml(html, HtmlCompat.FROM_HTML_MODE_COMPACT)
【補足】
参考:公式ドキュメント
2. スタイルの適用
以下、要点となります。
-
buildAnnotatedString
を使用して、「1. HTMLCompatを使ってHTMLを変換する」のSpanned
にスタイルを適応します。【補足1】 -
spanned.getSpans
メソッドを使用して、指定された範囲内のスタイルなどを取得します。【補足2】 -
when
を使用してForegroundColorSpan
の場合、テキストの色を設定するよう条件分岐をします。【補足3】 -
spanned.getSpanStart(it)
とspanned.getSpanEnd(it)
を使用して、スタイルを適用する範囲を指定します。 - 最後に
append(spanned)
で変換されたスタイルを追加します。
【補足1】
【補足2】
CharacterStyleは文字のスタイルを適応するための抽象クラスで、具体的には以下のようなスタイルを適応するサブクラスがあります。
- ForegroundColorSpan: 文字の前景色(テキストの色)を変更します。
- BackgroundColorSpan: 文字の背景色を変更します。
- StyleSpan: 文字のスタイル(太字、斜体など)を変更します。
- UnderlineSpan: 文字に下線を引きます。
- StrikethroughSpan: 文字に取り消し線を引きます。
ここでは、Spannedの文字全体からスタイル適応に該当する文字部分を取得しているイメージです。
今回は文字色を変えたいのでForegroundColorSpanが返ってくることを期待します!
参考:公式ドキュメント
【補足3】
サンプルコード(閉じれます)
val annotatedText = buildAnnotatedString {
spanned.getSpans(0, spanned.length, CharacterStyle::class.java).forEach {
// フォントのスパンにスタイルを適用
when (it) {
is ForegroundColorSpan -> {
// itはForegroundColorSpanのインスタンス
val color = it.foregroundColor
addStyle(
SpanStyle(
color = Color(color),
),
spanned.getSpanStart(it),
spanned.getSpanEnd(it),
)
}
else -> {
// 何もしない
}
}
}
append(spanned)
}
3. テキストの表示
スタイルが適用されたテキストを表示します。
Text(
modifier = modifier,
text = annotatedText,
style = textStyle.merge(
TextStyle(fontSize = fontSize),
),
)
ここまでの全コード
ここまでのコード(閉じれます)
@Composable
fun HtmlText(
html: String,
fontSize: TextUnit,
modifier: Modifier = Modifier,
textStyle: TextStyle = LocalTextStyle.current,
) {
val spanned = HtmlCompat.fromHtml(html, HtmlCompat.FROM_HTML_MODE_COMPACT)
val annotatedText = buildAnnotatedString {
spanned.getSpans(0, spanned.length, CharacterStyle::class.java).forEach {
when (it) {
is ForegroundColorSpan -> {
val color = it.foregroundColor
addStyle(
SpanStyle(
color = Color(color),
),
spanned.getSpanStart(it),
spanned.getSpanEnd(it),
)
}
else -> {
// 何もしない
}
}
}
append(spanned)
}
Text(
modifier = modifier,
text = annotatedText,
style = textStyle.merge(
TextStyle(fontSize = fontSize),
),
)
}
③ 作成したComposable関数を必要な場所で呼び出して表示する
@Composable
fun SampleScreen() {
val sampleHtml = "ご覧いただきありがとうございます。HTML形式のテキストを<font color='#ed293e'>一部赤色の文字で表示します。</font>"
HtmlText(
html = sampleHtml,
)
}
以上となります。
最後までご覧いただきありがとうございました