你或许想尝试这样的方法。
基本上,它是一个ReplacementSpan
,它会拿取应用在其上的文字,将其分为两部分,并在画布上绘制它们。大小因素和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"
),然后使用正则表达式处理字符串并添加相应的SuperSubSpans
,这样您就不需要手动完成了。但实际的Span部分会多多少少相同。
我不会尝试弯曲TextView小部件来实现这个。相反,您可以轻松制作自己的小部件,其中包含两种不同的绘画:一个用于元素名称(大字体大小),另一个用于数字(小字体大小,斜体)。
您将制作适当的setter并单独存储每个属性,而不是存储大的可跨度或字符串。
您还可以轻松地水平和垂直对齐(数字在元素名称的顶部和底部)
要计算宽度,您可以拥有一个属性来调整数字和元素名称之间的填充。然后,您可以使用每个绘画来计算文本宽度并添加所有这些内容(不要忘记添加小部件填充值)。
如果您只需要下标和上标,请使用SubscriptSpannable和SuperscriptSpannable。如果由于某种原因您不喜欢它们的绘制方式,您可以随时创建自定义spannable并自行绘制。
使用以下代码解决问题...
TextView txt = (TextView)findViewById(R.id.txt_label);
txt.setText(Html.fromHtml("<sup>9</sup><sub>4</sub>Be"));
你可以跟随我的步骤。这会对你有所帮助,例如:
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" + "<sup>" + "2" + "</sup>" + " + "
+ "b" + "<sup>" + "2" + "</sup>" + "=" + "(" + "a-b" + ")"
+ "<sup>" + "2" + "</sup>" + " + " + "2ab"));
water.setText(Html.fromHtml("H" + "<sub>" + "2" + "</sub>" + "O"));
}
}
这里是上标和下标的豪宅。
还有 activity_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:gravity="center"
tools:context="com.example.textview.MainActivity" >
<TextView
android:id="@+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="TextView" />
<TextView
android:id="@+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="TextView" />
</LinearLayout>
祝你好运!
你也可以参考我的答案link。只需使用SpannableString
即可解决你的问题。
SpannableString styledString = new SpannableString("9-10th STD");
styledString.setSpan(new SuperscriptSpan(), 4, 6, 0);
textView.setText(styledString);
并将android:textAllCaps="false"
放入您的代码中