![見出し画像](https://assets.st-note.com/production/uploads/images/145470678/rectangle_large_type_2_3c26255e00c9fa977cda1b87e4a06a9f.png?width=800)
Now In REALITY Tech #115 ComposeのTextがHTMLに対応したので使ってみた
こんにちは、Androidエンジニアのtkcです。
最近は社会の理想的な制度について思いを馳せています。
![](https://assets.st-note.com/img/1719470084832-keLLLeAoO0.png)
先日のGoogle I/O 2024の記事を読んでいると、下記の記事を見つけました。
Text
Text now supports inline links and basic HTML formatting via the new AnnotatedString.fromHtml() extension. This converts basic HTML formatting, including links to an AnnotatedString, which can then be rendered by Compose.
ちょうど去年自分が書いたHTMLをTextで扱う機能がComposeのTextに実装されているようなので、詳細を調べてみました。
実際に使ってみる
まずはテキストにHTMLタグを反映する
公式ドキュメント
ChangeLogをみると1.7.0-alpha07でAnnotatedStringにfromHtmlのメソッドが追加された様子
Stable最新の1.6.8には追加されていないので、とりあえずベータリリース最新の1.7.0-beta04を使う
// First, download a string as a plain text using one of the resources' methods. At this stage
// you will be handling plurals and formatted strings in needed. Moreover, the string will be
// resolved with respect to the current locale and available translations.
val string = stringResource(id = R.string.tagged_text))
// Next, convert a string marked with HTML tags into AnnotatedString to be displayed by Text
val styledAnnotatedString = AnnotatedString.fromHtml(htmlString = string)
BasicText(styledAnnotatedString)
<string name="tagged_text"><a href="https://reality.app"> REALITY </a> へようこそ!!!!!!<br/><font color="RED">123456</font><big>7890</big>1234567890</string>
とりあえずドキュメントに書いてあるようにやってみると…
![](https://assets.st-note.com/img/1719456768049-thmIklXOEY.png?width=800)
![](https://assets.st-note.com/img/1719470204740-CIlwdzHPjZ.png)
前回やったときにHTMLエスケープしないとだめだったような記憶を思い出しながらドキュメントを見ていると、やはりHTMLエスケープは必要と書いてあった。
If you define your string in the resources, make sure to use HTML-escaped opening brackets "<" instead of "<".
詳しくはResourceのほうのドキュメントにより詳しく書いてあった
そこでリソースでHTMLエスケープをしてみると…
<string name="tagged_text_with_escape"><a href="https://reality.app"> REALITY </a> へようこそ!!!!!!<br>123456<big><font color="RED">7890</font></big>1234567890</string>
反映されました
![](https://assets.st-note.com/img/1719457209361-XpmX1IA1GK.png?width=800)
リンクをクリックで開く
AnnotatedStringにlinkInteractionListenerという引数があり、
説明を見ると下記のように書いてあるのでリンクを検出してクリック時にブラウザでリンクを開いてくれるのかなと思いました。
a listener that will be attached to links that are present in the string and triggered when user clicks on those links. When set to null, which is a default, the system will try to open the corresponding links with the androidx.compose.ui.platform.UriHandler composition local
val localUriHandler = LocalUriHandler.current
val styledAnnotatedString = AnnotatedString.fromHtml(
htmlString = string,
linkStyles = TextLinkStyles(
style = SpanStyle(
color = Color.Blue,
)
),
linkInteractionListener = { annotation ->
// Toast.makeText(context,"hoge", Toast.LENGTH_SHORT).show() // クリックしてもここの処理が走らない
// val url = annotation as? LinkAnnotation.Url ?: return@fromHtml
// localUriHandler.openUri(url.url)
}
そこでこのコードでAnnotatedStringを書いてみたのですが、
<a>タグで囲ったREALITYの部分のスタイルが変わることも、クリックでリンクが開かれることもありませんでした。
![](https://assets.st-note.com/img/1719468375634-odtQdhN0pQ.png)
クリック時にlinkInteractionListenerの処理が走らないので、<a>タグで囲った部分がリンクとして認識されていないようです。
<a>タグではなく他のタグが必要なのかと疑いましたが、ドキュメントに手がかりを見つけることができませんでした。
ViewのTextでは<a>タグでリンクを開くことができたので、<a>が使えると思っていたのですが、ComposeのTextではリンクを開くことはできませんでした。
まだこの機能はBeta版なので、今後なにか変更があるかもしれませんが
現状ではこのような挙動であることがわかりました。
まとめ
AnnotatedStringにfromHtmlというメソッドが追加され、ComposeのTextでもHTMLが使えるようになった
そのため、以前ブログに書いたようなAndroidViewをつかってViewのTextを使う必要がなくなった
文言リソースから取得する場合はHTMLエスケープが必要なのはViewのときと変わらず
ViewのTextではリンクとして動作した<a>がComposeでは現状リンクとして動作しない
感想
AndroidViewを使わなくて良くなったのでより簡単になったのは良いのですが、
依然リソースではHTMLエスケープが必要であるのと、
<a>タグがリンクにならないようなので、現状ちょっと使いにくいかなと思いました。
今後<a>タグをつけるだけでブラウザが開くようになったらかなり便利になるんじゃないかと思うので期待して待ちましょう。