У меня есть следующая строка RM123.456 . я бы хотел
Я почти достигла этого, используя
spannableString.setSpan(new RelativeSizeSpan(0.50f), 0, index, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); textView.setText(spannableString, TextView.BufferType.SPANNABLE);
Результат выглядит так:
Тем не менее, он выровнен по низу. Он не соответствует вершине.
Я пытаюсь использовать SuperscriptSpan
. Это выглядит как
Он не делает то, что я хочу, как
SuperscriptSpan
не уменьшает текст. Я не могу контролировать его размер. SuperscriptSpan
сделает текст «над верхним выравниванием» Могу ли я узнать, как сделать выравнивание RelativeSizeSpan точно таким же ?
Это то, чего я хочу достичь.
Обратите внимание, что мы не хотим идти на 2 решения TextViews.
Однако я сделал так:
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
– это просто быстрый взлом без особого тестирования, но, похоже, он работает нормально. Он полностью полагается на Paint.getTextBounds()
чтобы найти наилучшее значение для baselineShift
, но, возможно, был бы лучший подход.
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; } }
Вы можете достичь максимальной гравитации, создав собственный класс 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, о которой идет речь: два разных стиля в одном текстовом режиме с разной степенью тяжести и высоты
Лучшим подходящим решением является html.
Я предпочту для этих решений, он поддерживает все версии Android, а также устройства.
Вот пример, возьмите его так же, как текст
<p><sup>TM</sup> 123.456.</p>
Я получаю результат в android
TM 123.456.
Вы можете легко отображать текст в Textview в android с помощью
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);
Hardcoded для целей тестирования,
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
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. Также вы можете добавить верхний индекс справа и слева. (Здесь я прокомментировал весь код, если вы хотите, можете попробовать …)
Класс для верхнего выравнивания, который следует использовать вместо 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);