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

时间:2014-06-02 08:36:20

标签: android textview subscript superscript

在下图中的示例中:

enter image description here

如何使上标和下标数字对齐以产生如下所示的通用科学记数

enter image description here

TextView中的

?如果有使用SpannableReplacementSpan的方式,我希望看到一个有效的例子。谢谢。

6 个答案:

答案 0 :(得分:14)

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

它的基础是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);

产生以下结果:

Sample

稍微好一点的解决方案是为这些字符串设置一种特殊的格式(例如"{9,4}Be -> {2000,127}Jo")并使用正则表达式处理字符串并添加相应的SuperSubSpans,这样就不会让你感到厌烦。 ; t需要手动操作。但实际的Span部分或多或少相同。

答案 1 :(得分:0)

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

答案 2 :(得分:0)

使用此代码进行解决....

TextView txt = (TextView)findViewById(R.id.txt_label); txt.setText(Html.fromHtml("<sup>9</sup><sub>4</sub>Be"));

答案 3 :(得分:0)

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

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>

祝你好运!

答案 4 :(得分:0)

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

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

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

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

答案 5 :(得分:0)

你也可以参考我的答案link 只需使用SpannableString来解决您的问题。

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

并放置android:textAllCaps="false"