Android 本身的 TextView 雖然支援簡單的 Html, 也有 HtmlCompat.fromHtml 支援把 Html 轉成 Spanned 來顯示, 但是支援的 Html tag 有限, 顯示效果也跟網頁有蠻大的差別。
想到 Markdown 本身有支援 Html 語法, 也有人開發了 Markdown 的 Compose 元件, 拿來用用看差別。
HtmlCompat 的效果 #
binding.textviewFirst.setText(
HtmlCompat.fromHtml(
"""
<ul>
<li>Milk</li>
<li>
Cheese
<ul>
<li>Blue cheese</li>
<li>Feta</li>
</ul>
</li>
</ul>
<ol>
<li>first item</li>
<li>second item
<ol>
<li> 2-1 </li>
<li> 2-2 </li>
</ol>
</li>
<li>third item</li>
</ol>
""".trimIndent(),
HtmlCompat.FROM_HTML_MODE_COMPACT
)
)
這段 Html 顯示預期如下
<ul>有不同的 Bullet 跟 縮排<ol>可以顯示數字
- Milk
-
Cheese
- Blue cheese
- Feta
- first item
- second item
- 2-1
- 2-2
- third item
實際上顯示是這樣, 沒有支援 <ol>, 縮排也不明顯。
compose-markdown #
compose-markdown 這個元件, 除了 Markdown 內容, 也可以混雜 Html。
binding.compose.setContent {
MarkdownText(
isTextSelectable = true,
linkColor = Color.Red,
markdown = """
## Compose Markdown
<h1>Heading 1</h1>
<h2>Heading 2</h2>
<h3>Heading 3</h3>
<h4>Heading 4</h4>
<h5>Heading 5</h5>
<h6>Heading 6</h6>
</p>
## Unordered List
<ul>
<li>Milk</li>
<li>
Cheese
<ul>
<li>Blue cheese</li>
<li>Feta</li>
</ul>
</li>
</ul>
</p>
## Ordered List
<ol>
<li>first item</li>
<li>second item
<ol>
<li> 2-1 </li>
<li> 2-2 </li>
</ol>
</li>
<li>third item</li>
</ol>
## Links
* Markdown
* [Link](https://example.com)
<a href="https://www.google.com/">Google</a>
"""
)
}
測試結果
<h1>…<h6>都沒有問題<ul>的 Bullet 大小比較接近瀏覽器顯示, 也有正確縮排<ol>有正確縮排, 不過第二層是用同樣的數字- Markdown 語法的連結跟 HTML
<a href>都可以正常點擊, 打開預設瀏覽器 - 可以修改 Link 顏色, 自訂 Link 點擊 callback
- 可以選取內容
- 有更多字型, 內容相關的 style 設定
相關 Library #
compose-markdown (包裝成 ComposeView )
io.noties.markwon (Markdown 轉成 Android Spanned )。如果不用 Compose 也可以直接用這個 Library, 有 Android Sample App
commonmark-java (解析 Markdown 內容)