如何使RelativeSizeSpanalignment顶部

我有以下stringRM123.456 。 我想要

  • 使RM相对较小
  • RM完全alignment

我几乎可以通过使用来实现它

spannableString.setSpan(new RelativeSizeSpan(0.50f), 0, index, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); textView.setText(spannableString, TextView.BufferType.SPANNABLE); 

结果看起来像

在这里输入图像说明

然而,它是alignment的底部。 它不alignment顶部。

我尝试使用SuperscriptSpan 。 看起来像

在这里输入图像说明

它不会做我想要的

  • SuperscriptSpan不会使文本变小。 我无法控制其大小。
  • SuperscriptSpan将使文本“在顶部alignment”

我可以知道,我怎样才能使RelativeSizeSpan 完全alignment?

这是我想要达到的。

在这里输入图像说明

请注意,我们不希望使用2个TextViews解决scheme。

Solutions Collecting From Web of "如何使RelativeSizeSpanalignment顶部"

不过我这样做了:

在这里输入图像说明

activity_main.xml

 <TextView android:id="@+id/txtView" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="50dp" android:textSize="26sp" /> 

MainActivity.java

 TextView txtView = (TextView) findViewById(R.id.txtView); SpannableString spannableString = new SpannableString("RM123.456"); spannableString.setSpan( new TopAlignSuperscriptSpan( (float)0.35 ), 0, 2, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE ); txtView.setText(spannableString); 

TopAlignSuperscriptSpan.java

 private class TopAlignSuperscriptSpan extends SuperscriptSpan { //divide superscript by this number protected int fontScale = 2; //shift value, 0 to 1.0 protected float shiftPercentage = 0; //doesn't shift TopAlignSuperscriptSpan() {} //sets the shift percentage TopAlignSuperscriptSpan( float shiftPercentage ) { if( shiftPercentage > 0.0 && shiftPercentage < 1.0 ) this.shiftPercentage = shiftPercentage; } @Override public void updateDrawState( TextPaint tp ) { //original ascent float ascent = tp.ascent(); //scale down the font tp.setTextSize( tp.getTextSize() / fontScale ); //get the new font ascent float newAscent = tp.getFontMetrics().ascent; //move baseline to top of old font, then move down size of new font //adjust for errors with shift percentage tp.baselineShift += ( ascent - ascent * shiftPercentage ) - (newAscent - newAscent * shiftPercentage ); } @Override public void updateMeasureState( TextPaint tp ) { updateDrawState( tp ); } } 

希望这会帮助你。

我看了一下RelativeSizeSpan ,发现一个相当简单的实现。 所以你可以为你的目的实现你自己的RelativeSizeSpan 。 这里唯一的区别是它没有实现ParcelableSpan ,因为这只是用于框架代码。 AntiRelativeSizeSpan只是一个快速的黑客,当然没有太多的testing,但它似乎工作正常。 它完全依赖于Paint.getTextBounds()来为baselineShiftfind最好的值,但也许会有更好的方法。

原始的RelativeSizeSpan AntiRelativeSizeSpan

 public class AntiRelativeSizeSpan extends MetricAffectingSpan { private final float mProportion; public AntiRelativeSizeSpan(float proportion) { mProportion = proportion; } public float getSizeChange() { return mProportion; } @Override public void updateDrawState(TextPaint ds) { updateAnyState(ds); } @Override public void updateMeasureState(TextPaint ds) { updateAnyState(ds); } private void updateAnyState(TextPaint ds) { Rect bounds = new Rect(); ds.getTextBounds("1A", 0, 2, bounds); int shift = bounds.top - bounds.bottom; ds.setTextSize(ds.getTextSize() * mProportion); ds.getTextBounds("1A", 0, 2, bounds); shift += bounds.bottom - bounds.top; ds.baselineShift += shift; } } 

你可以通过创build一个自定义的MetricAffectingSpan类来实现最重要的引力

这里是自定义类的代码:

 public class CustomCharacterSpan extends MetricAffectingSpan { double ratio = 0.5; public CustomCharacterSpan() { } public CustomCharacterSpan(double ratio) { this.ratio = ratio; } @Override public void updateDrawState(TextPaint paint) { paint.baselineShift += (int) (paint.ascent() * ratio); } @Override public void updateMeasureState(TextPaint paint) { paint.baselineShift += (int) (paint.ascent() * ratio); } } 

应用跨度:

 spannableString.setSpan(new RelativeSizeSpan(0.50f), 0, index, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); spannableString.setSpan(new CustomCharacterSpan(), 0, index, SpannableString.SPAN_EXCLUSIVE_EXCLUSIVE); textView.setText(spannableString, TextView.BufferType.SPANNABLE); 

输出:

在这里输入图像说明

有关MetricAffectingSpan的更多信息,请访问: http : //developer.android.com/reference/android/text/style/MetricAffectingSpan.html

Custom MetricAffectingSpan逻辑参考: 单个文本视图中的两种不同的样式,具有不同的重力和高度

最好的解决scheme是去与HTML。

我会喜欢这个解决scheme,它支持所有的Android版本以及设备。

这里是一个例子,你想要的文本相同

 <p><sup>TM</sup> 123.456.</p> 

我在android中获得结果

TM 123.456。

你可以很容易地在android中用textview显示文本

Html.fromText("YOUR_STRING_INHTML");

希望能帮助到你。

你必须使用像下面的HTML标签下标和上标。它的作品像魅力。

  ((TextView) findViewById(R.id.text)).setText(Html.fromHtml("<sup><small>2</small></sup>X")); 

在这里输入图像说明

要么

你也可以使用下面的代码:

 String titleFirst = "Insert GoTechTM device into the vehicle\'s OBDII port."; SpannableStringBuilder cs = new SpannableStringBuilder(titleFirst); cs.setSpan(new SuperscriptSpan(), titleFirst.indexOf("TM"), titleFirst.indexOf("TM")+2, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); cs.setSpan(new RelativeSizeSpan((float)0.50), titleFirst.indexOf("TM"), titleFirst.indexOf("TM")+2, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); txtPairInstructionFirst.setText(cs); 

我已经在我的一个应用程序中实现了这个。

  <TextView android:id="@+id/txt_formatted_value" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:textColor="#000000" android:textSize="28dp" /> 

在活动/ Frgament.class

  myTextView = (TextView) view.findViewById(R.id.txt_formatted_value); 

硬编码用于testing目的,

 String numberValue = "123.456"; myTextView.setText(UtilityClass.getFormattedSpannedString("RM"+numberValue, numberValue.length(),0)); 

在你的包中添加这个类,

 public class SuperscriptSpanAdjuster extends MetricAffectingSpan { double ratio = 0.5; public SuperscriptSpanAdjuster() { } public SuperscriptSpanAdjuster(double ratio) { this.ratio = ratio; } @Override public void updateDrawState(TextPaint paint) { paint.baselineShift += (int) (paint.ascent() * ratio); } @Override public void updateMeasureState(TextPaint paint) { paint.baselineShift += (int) (paint.ascent() * ratio); } 

}

在UntilityClass.class中创build格式化方法

  public static SpannableString getFormattedSpannedString(String value, int mostSignificantLength, int leastSignificantLength){ SpannableString spanString = new SpannableString(value); /* To show the text in top aligned(Normal)*/ spanString.setSpan(new SuperscriptSpanAdjuster(0.7), 0,spanString.length()-mostSignificantLength-leastSignificantLength, SpannableString.SPAN_EXCLUSIVE_EXCLUSIVE); /* Show the number of characters is normal size (Normal)*/ spanString.setSpan(new RelativeSizeSpan(1.3f), 0,spanString.length()-mostSignificantLength-leastSignificantLength, 0); /*To set the text style as bold(MostSignificant)*/ //spanString.setSpan(new StyleSpan(Typeface.BOLD), spanString.length()-mostSignificantLength-leastSignificantLength, spanString.length()-leastSignificantLength, 0); /*To set the text color as WHITE(MostSignificant)*/ //spanString.setSpan(new ForegroundColorSpan(Color.WHITE), spanString.length()-mostSignificantLength-leastSignificantLength, spanString.length()-leastSignificantLength, 0); /*Show the number of characters as most significant value(MostSignificant)*/ spanString.setSpan(new RelativeSizeSpan(2.3f), spanString.length()-mostSignificantLength-leastSignificantLength, spanString.length()-leastSignificantLength, 0); /* To show the text in top aligned(LestSignificant)*/ spanString.setSpan(new SuperscriptSpanAdjuster(1.2), spanString.length()-leastSignificantLength, spanString.length(), SpannableString.SPAN_EXCLUSIVE_EXCLUSIVE); /*To set the text style as bold(LestSignificant)*/ //spanString.setSpan(new StyleSpan(Typeface.BOLD), spanString.length()-leastSignificantLength, spanString.length(), 0); /*Show the number of characters as most significant value(LestSignificant)*/ spanString.setSpan(new RelativeSizeSpan(0.8f), spanString.length()-leastSignificantLength, spanString.length(), 0); return spanString; } 

使用这种方法,你可以做更多的马戏团像改变文字样式,分别为SuperScript的颜色。 你也可以在右边和左边添加上标(这里我评论了所有的代码,如果你想可以试一下…)

在这里输入图像说明 在这里输入图像说明 在这里输入图像说明

顶部alignment的类应该用来代替RelativeSizeSpan(不是附加的):

 import android.text.TextPaint; import android.text.style.MetricAffectingSpan; public class TopRelativeSizeSpan extends MetricAffectingSpan { private final float mProportion; public TopRelativeSizeSpan(float proportion) { mProportion = proportion; } @Override public void updateDrawState(TextPaint ds) { ds.baselineShift += (mProportion - 1) * (ds.getTextSize() - ds.descent()); ds.setTextSize(ds.getTextSize() * mProportion); } @Override public void updateMeasureState(TextPaint ds) { updateDrawState(ds); } } 

和用法:

 spannableString.setSpan(new TopRelativeSizeSpan(0.50f), 0, index, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); textView.setText(spannableString, TextView.BufferType.SPANNABLE);