如何在TextView中创建垂直对齐的上标和下标

图中的示例中:

在此处输入图像描述

如何使上标和下标数字对齐以产生如下的常见科学记数法

在此处输入图像描述

TextView ? 如果有使用SpannableReplacementSpan我想看一个有效的例子。 谢谢。

你可能想尝试这样的事情。

它是一个基础上的一个ReplacementSpan ,它接受它所应用的文本,将它分成两部分,并在canvas上绘制它们。 尺寸因子和y平移在某种程度上是精心挑选的。 我希望它有用(或者至少你或其他人可以在它上面构建)。

 public class SuperSubSpan extends ReplacementSpan { @Override public int getSize(Paint paint, CharSequence text, int start, int end, FontMetricsInt fm) { text = text.subSequence(start, end); String[] parts = text.toString().split(","); Paint p = getSuperSubPaint(paint); return (int) Math.max(p.measureText(parts[0]), p.measureText(parts[1])); } private static TextPaint getSuperSubPaint(Paint src) { TextPaint paint = new TextPaint(src); paint.setTextSize(src.getTextSize() / 2.5f); return paint; } @Override public void draw(Canvas canvas, CharSequence text, int start, int end, float x, int top, int y, int bottom, Paint paint) { text = text.subSequence(start, end); String[] parts = text.toString().split(","); Paint p = getSuperSubPaint(paint); float width1 = p.measureText(parts[0]); float width2 = p.measureText(parts[1]); float maxWidth = Math.max(width1, width2); canvas.drawText(parts[0], x + (maxWidth - width1), y - (bottom - top) / 3f, p); canvas.drawText(parts[1], x + (maxWidth - width2), y + (bottom - top) / 10f, p); } } 

然后用它作为:

 Spannable str = new SpannableString("9,4Be -> 2000,127Jo"); str.setSpan(new SuperSubSpan(), 0, 3, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); str.setSpan(new SuperSubSpan(), 9, 17, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); mTextView.setText(str); 

产生以下结果:

样品

一个稍微好一点的解决方案是为这些字符串设置一个特殊格式(例如"{9,4}Be -> {2000,127}Jo" )并使用正则expression式处理字符串并添加相应的SuperSubSpans ,这样就可以了你不需要手动。 但实际的Span部分或多或少相同。

如果您只想要下标和上标,请使用SubscriptSpannable和SuperscriptSpannable。 如果你不喜欢那些因某些原因而抽出的东西,你可以随时自定义并自行绘制。

使用此代码解决方案….

TextView txt = (TextView)findViewById(R.id.txt_label); txt.setText(Html.fromHtml("94Be"));

你可以一步一步跟我来。 你从这里得到帮助。 如

MainActivity.java

 public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); TextView txtView = (TextView) findViewById(R.id.textView1); TextView water = (TextView) findViewById(R.id.textView2); txtView.setText(Html.fromHtml("a" + "" + "2" + "" + " + " + "b" + "" + "2" + "" + "=" + "(" + "ab" + ")" + "" + "2" + "" + " + " + "2ab")); water.setText(Html.fromHtml("H" + "" + "2" + "" + "O")); } } 

这里是大厦上标和子大厦下标。

和activity_main.xml

     

祝你好运!

我不会尝试弯曲TextView小部件来实现它。 相反,您可以轻松制作具有2种不同颜色的自己的小部件:一个用于元素名称(大字体大小),另一个用于数字(小尺寸,斜体)。

您可以制作适当的setter并分别存储每个属性,而不是存储大的spannable或字符串。

您还可以轻松地水平和垂直对齐(元素名称顶部和底部的数字)

要计算宽度,您可以使用属性来调整数字和元素名称之间的填充。 然后,您可以使用每个绘制来计算文本宽度并添加所有这些(不要忘记添加小部件填充值)。

你也可以在这个链接中引用我的答案简单地使用SpannableString来解决你的问题。

  SpannableString styledString = new SpannableString("9-10th STD"); styledString.setSpan(new SuperscriptSpan(), 4, 6, 0); textView.setText(styledString); 

并把你的android:textAllCaps="false"