遗憾的是,科学和数学在 Android 平台上从未得到足够的重视。也许这是一个简单的问题,但我完全是 javascript 的花花公子,所以我很难理解如何解决这个问题。
我想做的很简单:我只需要使用渲染数学方程。它可以是 MathJax 或 JqMath 或任何小而快的东西。如果我必须在 webview 中执行此操作,如何在同一个 webview 中显示段落中的纯文本和格式化方程?
(任何人都提出了其他显然有效的方法,我也会认为这是解决方案)
到目前为止我做了什么:
我开始使用 MathJax 将公式放入 webview (我不知道那里是否有任何成功的 jqMath 用例?有人愿意分享他们的经验吗?)我可以像独立的MathJax App一样重现所有功能。在该应用程序中,用户在 EditText 字段中键入字符串,一旦用户按下按钮进行确认,MathJax 将在 Latex 中呈现公式。
我不需要用户确认。我认为这应该更容易,因为没有用户交互,但不知何故,方程式永远不会显示。我知道我一定遗漏了一些东西,因为独立的 MathJax 中的代码是用于用户输入的。我应该修改代码的哪一部分以直接从字符串渲染方程,例如 \sqrt{b^2-4ac} ?这是 webview 的初始标题:
WebView w = (WebView) findViewById(R.id.webview);
w.getSettings().setJavaScriptEnabled(true);
w.getSettings().setBuiltInZoomControls(true);
w.loadDataWithBaseURL("http://bar", "<script type='text/x-mathjax-config'>"
+"MathJax.Hub.Config({ showMathMenu: false, "
+"jax: ['input/TeX','output/HTML-CSS'], "
+"extensions: ['tex2jax.js'], "
+"TeX: { extensions: ['AMSmath.js','AMSsymbols.js',"
+"'noErrors.js','noUndefined.js'] } "
+"});</script>"
+"<script type='text/javascript' "
+"src='file:///android_asset/MathJax/MathJax.js'"
+"></script><span id='math'></span>","text/html","utf-8","");
以下是用户在输入edittext后按下按钮时原始webview的加载方式:
WebView w = (WebView) findViewById(R.id.webview);
EditText e = (EditText) findViewById(R.id.edit);
w.loadUrl("javascript:document.getElementById('math').innerHTML='\\\\["
+doubleEscapeTeX(e.getText().toString())
+"\\\\]';");
w.loadUrl("javascript:MathJax.Hub.Queue(['Typeset',MathJax.Hub]);");
private static String doubleEscapeTeX(String s) {
String t="";
for (int i=0; i < s.length(); i++) {
if (s.charAt(i) == '\'') t += '\\';
if (s.charAt(i) != '\n') t += s.charAt(i);
if (s.charAt(i) == '\\') t += "\\";
}
return t;
}
我试图用硬编码的字符串替换
w.loadUrl("javascript:document.getElementById('math').innerHTML='\\\\["
+doubleEscapeTeX("sample string")
+"\\\\]';");
但它不起作用,文本"sample string"
甚至不会出现在 webview 中。
[解决方案] 见乔的回答
为了详细说明他的答案,这是一个关于如何以纯文本设置句子,然后以显示形式显示格式化方程式的示例(全部在单个 webview 中):
将上面的最后一行替换为
+"></script><span id='math'></span>","text/html","utf-8","");
和
+"></script><span id='text'>This is plain text.</span> <span id='math'></span>", "text/html", "utf-8", "");
然后打电话
w.setWebViewClient(new WebViewClient() {
@Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
if (!url.startsWith("http://bar"))
return;
w.loadUrl("javascript:document.getElementById('math').innerHTML='\\\\["
+doubleEscapeTeX("\\sqrt{b^2-4ac}") + "\\\\]';");
w.loadUrl("javascript:MathJax.Hub.Queue(['Typeset',MathJax.Hub]);");
}
});
这将设置一个字符串这是普通字体的纯文本,并在 webview 中居中显示公式。
编辑(Android 4.4 问题)
从 Android KitKat 开始,您必须将所有行替换loadUrl(...)
为evaluateJavascript(...)
. 但这仅适用于 KitKat(API 19 或更高版本),因此您需要先进行 SDK 版本检查。例如:
if (android.os.Build.VERSION.SDK_INT < 19) {
w.loadUrl("javascript:MathJax.Hub.Queue(['Typeset',MathJax.Hub]);");
} else {
w.evaluateJavascript("javascript:MathJax.Hub.Queue(['Typeset',MathJax.Hub]);",null);
}
更新(从 MATHJAX 2.5 开始)
由于存在文件夹更改,以前的代码将无法在最新版本的 MathJax 上运行。此外,最小化本地 MathJax 大小的推荐方法现在是使用Grunt。可以在此处找到减小 MathJax 大小的模板。
假设您已经成功减小了 MathJax 的大小,并且假设输出的是 HTML-CSS,下面是一个可以加载 MathJax 的简单版本:
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
final WebView w = (WebView) findViewById(R.id.webview);
w.getSettings().setJavaScriptEnabled(true);
w.getSettings().setBuiltInZoomControls(true);
String Url = "</style>"
+ "<script type='text/x-mathjax-config'>"
+ " MathJax.Hub.Config({" + " showMathMenu: false,"
+ " jax: ['input/TeX','output/HTML-CSS', 'output/CommonHTML'],"
+ " extensions: ['tex2jax.js','MathMenu.js','MathZoom.js', 'CHTML-preview.js'],"
+ " tex2jax: { inlineMath: [ ['$','$'] ], processEscapes: true },"
+ " TeX: {" + " extensions:['AMSmath.js','AMSsymbols.js',"
+ " 'noUndefined.js']" + " }"
+ " });"
+ "</script>"
+ "<script type='text/javascript' src='file:///android_asset/MathJax/MathJax.js'>"
+ "</script>"
+ "<p style=\"line-height:1.5; padding: 16 16\" align=\"justify\">"
+ "<span >";
// Demo display equation
url += "This is a display equation: $$P=\frac{F}{A}$$";
url += "This is also an identical display equation with different format:\\[P=\\frac{F}{A}\\]";
// equations aligned at equal sign
url += "You can also put aligned equations just like Latex:";
String align = "\\begin{aligned}"
+ "F\\; &= P \\times A \\\\ "
+ "&= 4000 \\times 0.2\\\\"
+ "&= 800\\; \\text{N}\\end{aligned}";
url += align;
url += "This is an inline equation \\sqrt{b^2-4ac}.";
// Finally, must enclose the brackets
url += "</span></p>";
mWebView.loadDataWithBaseURL("http://bar", url, "text/html", "utf-8", "");
mWebView.setWebViewClient(new WebViewClient() {
@Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
if (!url.startsWith("http://bar")) return;
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) {
view.loadUrl(JAVASCRIPT);
} else {
view.evaluateJavascript(JAVASCRIPT, null);
}
}
});
}
与乔斯的回答不同,不需要分隔文本或数学类型,MathJax 只会相应地格式化它们。
但是,似乎存在一个错误,即 KitKat 设备中的 webview 无法呈现大写字母“A”。欢迎任何知道方法的人为此提供解决方法。