我正在尝试创建一个用于直观操作代数的Android应用。有没有可以使用的库可以选择,如可点击的代数?理想的图书馆需要一些符号代数,例如以MathML形式,在屏幕上渲染它,并返回onTouch事件或类似事件,指示已触摸渲染代数的哪个部分。
例如,在二次公式中,用户可以触摸平方根中的4ac,这个库会告诉我平方根中的4ac已被触摸,所以我可以突出显示4ac让用户知道它被选中,并独立于周围的代数复制它。另一个例子是在等式中选择一个术语,以便应用程序可以修改或替换它。
任何等价物都可以;一个库可以返回一个方程的图形表示,并且还可以识别该方程的哪个部分在图形上给出了点击坐标的符号,这样就可以了。基本上我正在寻找一个MathML(或类似的)渲染器,它确切地知道渲染的每个位代表什么。
我看过symja,sympy和MathJax,我还没有找到任何办法,尽管我确实有点失落。这已经存在吗?
提前致谢。
答案 0 :(得分:2)
最直接的方法是将'onClick'属性直接添加到您使用的MathML中,并使用元素ID&从那里绑定Java / JavaScript方法。但据我所知,MathML支持'onClick'属性(但?)。
我作为黑客攻击做的是为每个可点击的MathML元素添加链接,然后为WebView重载WebViewClient的shouldOverrideUrlLoading()方法,以捕获被调用的链接。然后,如果您在链接的某处添加唯一ID值,则可以确定单击了哪个元素。
如果您的原始MathML如下所示:
<math xmlns="http://www.w3.org/1998/Math/MathML" display="block">
<msqrt>
<msup><mi>b</mi><mn>2</mn></msup>
<mo>−</mo>
<mn>4</mn><mi>a</mi><mi>c</mi>
</msqrt>
</math>
将其更改为:
<math xmlns="http://www.w3.org/1998/Math/MathML" display="block">
<msqrt href=id1>
<msup><mi>b</mi><mn>2</mn></msup>
<mo>−</mo>
<mstyle href=id2><mn>4</mn><mi>a</mi><mi>c</mi></mstyle>
</msqrt>
</math>
关于嵌套链接的注意事项。使用MathJax的HTML-CSS输出时,仅主动单击最低链接。但是,使用SVG输出时,从最低级别到最高级别按顺序调用每个链接。因此,对于我的建议,您将不得不使用MathJax的HTML-CSS输出。如果我找到一种方法让SVG工作,我会进行编辑。
这有关于此问题的一些StackOverflow问题的描述,您可以参考Android Devs网站了解具体内容(here),因此我不会详细介绍。基本上,shouldOverrideUrlLoading()将有一个url String,其中包含您为刚刚单击的MathML元素指定的链接。解析ID值并将其发送到可以使用它的函数,你就可以了。
这是我在项目中使用的代码。
public class MathmlLinksViewClient extends WebViewClient {
//protected MainActivity activity;
public MathmlLinksViewClient(MainActivity context) {
activity = context;
}
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
// Reroutes id int value to MainActivity method
activity.onMathmlClick(
Integer.valueOf(
// Method I wrote to parse ID from URL
HtmlIdFormat.getIdFromString(url) ) );
return true;
}
}
请注意,传递给此函数的url并不完全是您在MathML元素中包含的链接。每个这些都是在为WebView使用WebView.loadDataWithBaseUrl()方法时指定的主机链接的前缀。 (我假设你正在关注this guide to render MathML。)
如果您的视图操作任何其他HTML链接,您将需要添加if语句来分隔MathML元素链接和网站链接上的操作。同样,您可以研究如何有效地使用shouldOverrideUrlLoading()。
一个缺点是它会将蓝色链接颜色添加到所有链接对象。你应该可以通过mstyle声明将所有元素的颜色设置为黑色来在MathML中覆盖它,但我目前遇到了这样的问题。
我没有涵盖所有内容,但我希望这有帮助!