前言:
一直致力於為公司尋找更加高效的解決方案,作為一款K12線上教育App,功能中難免會有LaTeX數學公式的顯示需求,這部分公司已經實現了此功能,只是個人覺得在體驗和效率上還是不太好,今天來聊一下如何讓原生渲染LaTeX數學公式。
先了解一下LaTeX數學公式
什麼是Latex?感興趣的同學可以檢視百科:Latex百科。
Latex數學公式:就是通過Latex來表示一個數學公式,舉例說明:
例如:$$ \\[ \\sum_{k=1}^n k^2 = \\frac{1}{2} n (n+1).\\] $$
表示數學公式:
目前方案
由於之前一直沒有找到原生渲染latex數學公式的方案,所以之前的採用的方案比較簡單粗暴了點,直接通過Latex生成圖片的方式,然後客戶端通過自定義TextView實現圖文混排。
分析優缺點:
- 一道題目中有可能很多數學公式,會有大量的圖片下載需求
- 由於是圖片下載,在弱網環境下會導致下載過慢
- 由於是下載的圖片,渲染過程慢,記憶體開銷相對也大
選定方案
基於目前現狀,一直想著尋找替換方案,最近尋找了一下解決方案,驚奇的發現現在已經有支援Latex原生渲染的開源框架了。今天來學習使用一下。它就是:FlexibleRichTextView。
FlexibleRichTextView簡介
一個可以自行定義大部分標籤(比如你可以自己定義粗體為 <b></b>
或者 [bold][/bold]
等等),支援LaTeX、圖片、程式碼高亮、表格、引用以及許多文字樣式如粗體、斜體、居中、刪除線、下劃線等的庫。
gitHub地址:https://github.com/daquexian/FlexibleRichTextView
FlexibleRichTextView使用
1.)在專案根目錄的build.gralde
檔案裡新增:
allprojects {
repositories {
...
maven { url "https://jitpack.io" }
}
}
2.)在app
的 build.gradle
檔案中新增
compile 'com.github.daquexian:FlexibleRichTextView:0.8.2'
3.)具體使用
使用之前必須初始化 JLaTeXMath,在 Application 或其他地方新增
AjLatexMath.init(context); // init library: load fonts, create paint, etc.
如果希望自動識別程式碼段中的語言以實現高亮,在 Application 或其他地方新增
// train classifier on app start CodeProcessor.init(this);
要顯示富文字,只需要呼叫 flexibleRichTextView.setText(String text)
方法,例如
String richText = "[h][center]hi![/center][/h]" +
"[quote]This is quote[/quote]" +
"[code]print(\"Hello FlexibleRichTextView!\")[/code]" +
"Hello FlexibleRichTextView!\n" +
"This is LaTeX:\n" +
"$e^{\\pi i} + 1 = 0$";
flexibleRichTextView.setText(richText);
其他相關知識請非同步到:FlexibleRichTextView中文使用文件 本文主要是驗證對Latex的支援。
4.)使用舉例
在佈局中引入FlexibleRichTextView
<com.daquexian.flexiblerichtextview.FlexibleRichTextView android:id="@+id/test_text" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_gravity="center" android:layout_margin="10dp" />
新增一些Latex數學公式,看下具體展示情況
FlexibleRichTextView richTextView = (FlexibleRichTextView) findViewById(R.id.test_text); StringBuilder stringBuilder = new StringBuilder(); stringBuilder.append("$$\\sum_{i=1}^n a_i=0$$,"); stringBuilder.append("$$f(x)=x^{x^x}$$"); stringBuilder.append("$$f(x_1,x_x,\\ldots,x_n) = x_1^2 + x_2^2 + \\cdots + x_n^2 $$"); stringBuilder.append("$$\\left. \\frac{du}{dx} \\right|_{x=0}.$$"); stringBuilder.append("f(n) = \\begin{cases} \\frac{n}{2}, & \\text{if } n\\text{ is even} \\\\ 3n+1, & \\text{if } n\\text{ is odd} \\end{cases}"); stringBuilder.append("$$\\mbox{對任意的$x>0$}, \\mbox{有 }f(x)>0. $$"); stringBuilder.append("$$\\sqrt[n]{x_r_r_r} $$"); stringBuilder.append("$$ \\frac{x+2}{x} \\sqrt{x} $$"); stringBuilder.append("$$ \\[f(x,y,z) = 3y^2 z \\left( 3 + \\frac{7x+5}{1 + y^2} \\right).\\] $$"); stringBuilder.append("$$ P(x|c)=\\frac{P(c|x)\\cdot P(x)}{P(x)} $$"); stringBuilder.append("$$ \\Large x=\\frac{-b\\pm\\sqrt{b^2-4ac}}{2a} $$"); stringBuilder.append("$$ \\sum_{i=1}^n i = \\frac{n(n+1)}2 $$"); stringBuilder.append("$$ f(x)=\\int_{-\\infty}^x e^{-t^2}dt $$ 這道公式我也不知道怎麼做"); stringBuilder.append("$$ \\cos 2\\theta = \\cos^2 \\theta - \\sin^2 \\theta = 2 \\cos^2 \\theta - 1. $$"); stringBuilder.append("$$ \\displaystyle= \\frac{k(k+1)}{2}+k+1 $$"); stringBuilder.append("$$ \\frac{x}{2}-3=0 $$"); stringBuilder.append("$$ x=\\frac{3}{2} $$"); stringBuilder.append("$$ \\[ \\sum_{k=1}^n k^2 = \\frac{1}{2} n (n+1).\\] $$"); richTextView.setText(stringBuilder.toString());
展示效果
內部具體Latex展示是基於LatexTextView,然後將其新增到FlexibleRichTextView 容器中,由於專案中也會有其他的圖文混排的問題,所以直接使用FlexibleRichTextView是無法滿足需求的,需要基於LatexTextView進行二次開發。
總結:
本文主要驗證本地原生渲染Latex數學公式是否可行。接下來會對FlexibleRichTextView進行二次開發,來滿足專案的需求。