You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在无网络的Jetpack Compose安卓应用中显示LaTeX或数学公式?

如何在无网络的Jetpack Compose安卓应用中显示LaTeX或数学公式?

我之前也踩过类似的坑,很多库要么偷偷依赖网络,要么配置起来有各种小问题,这里给你几个亲测有效的离线方案:

方案一:用KaTeX本地渲染(推荐,轻量且渲染快)

KaTeX是轻量型的LaTeX渲染库,完全支持离线使用,只需要把它的核心资源打包到项目里就行:

  1. 准备离线资源
    下载KaTeX的压缩包后,解压出katex.min.js、katex.min.css,还有关键的fonts文件夹(缺了字体公式会显示乱码),把它们都放到项目的src/main/assets/katex/目录下。

  2. Compose组件实现
    在Compose里我们可以用AndroidView嵌入WebView,加载本地HTML来渲染公式:

    @Composable
    fun OfflineKaTeXView(latexText: String) {
        AndroidView(
            factory = { context ->
                WebView(context).apply {
                    settings.javaScriptEnabled = true
                    settings.allowFileAccess = true
                    // 强制禁止网络请求,确保完全离线
                    settings.blockNetworkLoads = true
                    // 拼接本地HTML模板,传入LaTeX内容
                    val htmlContent = """
                        <!DOCTYPE html>
                        <html>
                        <head>
                            <link rel="stylesheet" href="file:///android_asset/katex/katex.min.css">
                            <script src="file:///android_asset/katex/katex.min.js"></script>
                        </head>
                        <body style="margin:0; padding:8px;">
                            <span id="formula"></span>
                            <script>
                                katex.render("$latexText", document.getElementById("formula"), {
                                    throwOnError: false // 忽略渲染错误,避免应用崩溃
                                });
                            </script>
                        </body>
                        </html>
                    """.trimIndent()
                    loadDataWithBaseURL("file:///android_asset/", htmlContent, "text/html", "UTF-8", null)
                }
            },
            update = { webView ->
                // 更新公式时重新加载HTML
                val updatedHtml = """
                    <!DOCTYPE html>
                    <html>
                    <head>
                        <link rel="stylesheet" href="file:///android_asset/katex/katex.min.css">
                        <script src="file:///android_asset/katex/katex.min.js"></script>
                    </head>
                    <body style="margin:0; padding:8px;">
                        <span id="formula"></span>
                        <script>
                            katex.render("$latexText", document.getElementById("formula"), {
                                throwOnError: false
                            });
                        </script>
                    </body>
                    </html>
                """.trimIndent()
                webView.loadDataWithBaseURL("file:///android_asset/", updatedHtml, "text/html", "UTF-8", null)
            }
        )
    }
    
  3. 使用组件
    在你的Compose界面里直接调用即可:

    OfflineKaTeXView(latexText = "E=mc^2 \\quad \\text{or} \\quad \\int_{a}^{b} f(x) dx")
    

方案二:MathJax本地渲染(功能更全,适合复杂公式)

如果你的公式用到了KaTeX不支持的复杂LaTeX语法,可以用MathJax,步骤类似:

  1. 下载MathJax的离线包,把整个MathJax文件夹放到assets目录下。
  2. 同样用AndroidView包裹WebView,加载本地HTML调用MathJax渲染:
    @Composable
    fun OfflineMathJaxView(latexText: String) {
        AndroidView(
            factory = { context ->
                WebView(context).apply {
                    settings.javaScriptEnabled = true
                    settings.blockNetworkLoads = true
                    val htmlContent = """
                        <!DOCTYPE html>
                        <html>
                        <head>
                            <script src="file:///android_asset/MathJax/es5/tex-mml-chtml.js"></script>
                            <script>
                                MathJax.config = {
                                    loader: { load: ['[tex]/ams'] },
                                    tex: { packages: {'[+]': ['ams']} }
                                };
                            </script>
                        </head>
                        <body style="margin:0; padding:8px;">
                            $$ $latexText $$
                        </body>
                        </html>
                    """.trimIndent()
                    loadDataWithBaseURL("file:///android_asset/", htmlContent, "text/html", "UTF-8", null)
                }
            },
            update = { webView ->
                val updatedHtml = """
                    <!DOCTYPE html>
                    <html>
                    <head>
                        <script src="file:///android_asset/MathJax/es5/tex-mml-chtml.js"></script>
                        <script>
                            MathJax.config = {
                                loader: { load: ['[tex]/ams'] },
                                tex: { packages: {'[+]': ['ams']} }
                            };
                        </script>
                    </head>
                    <body style="margin:0; padding:8px;">
                        $$ $latexText $$
                    </body>
                    </html>
                """.trimIndent()
                webView.loadDataWithBaseURL("file:///android_asset/", updatedHtml, "text/html", "UTF-8", null)
            }
        )
    }
    

关键注意事项

  • 字体资源一定要打包,不然公式会显示成方块或乱码;
  • 开启throwOnError: false可以避免因LaTeX语法错误导致应用崩溃;
  • 也可以把HTML模板抽成单独的文件放到assets里,再通过JS接口传递LaTeX内容,这样代码会更整洁。

备注:内容来源于stack exchange,提问作者Ion Petrea

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.15 10:53:08