Intereting Posts

Как сделать RelativeSizeSpan выровненным вверх

У меня есть следующая строка RM123.456 . я бы хотел

  • Сделайте RM относительно небольшим
  • Сделайте RM выровненным вверх точно

Я почти достигла этого, используя

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

Результат выглядит так:

Введите описание изображения здесь

Тем не менее, он выровнен по низу. Он не соответствует вершине.

Я пытаюсь использовать SuperscriptSpan . Это выглядит как

Введите описание изображения здесь

Он не делает то, что я хочу, как

  • SuperscriptSpan не уменьшает текст. Я не могу контролировать его размер.
  • SuperscriptSpan сделает текст «над верхним выравниванием»

Могу ли я узнать, как сделать выравнивание RelativeSizeSpan точно таким же ?

Это то, чего я хочу достичь.

Введите описание изображения здесь

Обратите внимание, что мы не хотим идти на 2 решения TextViews.

Solutions Collecting From Web of "Как сделать RelativeSizeSpan выровненным вверх"

Однако я сделал так:

Введите описание изображения здесь

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 , но, возможно, был бы лучший подход.

Оригинальный 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; } } 

Вы можете достичь максимальной гравитации, создав собственный класс 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);