Comment faire RelativeSizeSpan aligner en haut
J'ai la chaîne suivante RM123. 456 . Je voudrais
- Faire RM relativement plus petit
- Faire RM aligné exactement au sommet
J'ai presque réussi à y parvenir en utilisant
spannableString.setSpan(new RelativeSizeSpan(0.50f), 0, index, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
textView.setText(spannableString, TextView.BufferType.SPANNABLE);
, Le résultat ressemble à
Cependant, il est aligné sur le fond. Il n'a pas d'aligner vers le haut.
J'essaie d'utiliser SuperscriptSpan
. Il ressemble à
Il ne fait pas ce que je veux comme
-
SuperscriptSpan
ne réduit pas le texte. Je ne suis pas capable de contrôler son dimensionnement. - {[1] } fera en sorte que le texte "sur le dessus s'alignera"
Puis-je savoir, comment puis-je aligner RelativeSizeSpan sur top exactement?
C'est ce que je souhaite réaliser.
Veuillez noter que nous ne souhaitons pas opter pour la solution 2 TextViews.
7 réponses
Cependant je l'ai fait de cette façon:
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 );
}
}
J'espère que cela vous aidera.
J'ai regardé le RelativeSizeSpan
et j'ai trouvé une implémentation plutôt simple. Donc, vous pouvez simplement implémenter votre propre RelativeSizeSpan
pour votre but. La seule différence ici est qu'il n'implémente pas ParcelableSpan
, car il est uniquement destiné au Code framework. AntiRelativeSizeSpan
est juste un hack rapide sans beaucoup de tests bien sûr, mais il semble fonctionner correctement. Il repose complètement sur Paint.getTextBounds()
pour trouver la meilleure valeur pour le baselineShift
, mais peut-être y aurait-il un meilleur approche.
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;
}
}
Vous pouvez atteindre la gravité supérieure en créant une classe metricaffectingspan personnalisée
Voici le code de la classe personnalisée:
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);
}
}
L'Application de la durée:
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);
Sortie:
Pour plus d'informations sur MetricAffectingSpan: http://developer.android.com/reference/android/text/style/MetricAffectingSpan.html
Logique Metricaffectingspan personnalisée référencée à partir de: deux styles différents dans un seul textview avec gravité différente et hieght
La meilleure solution appropriée est go avec html.
Je préférerai pour cette solution, il prend en charge dans toutes les versions android ainsi que les appareils.
Voici un exemple, prenez-le comme vous voulez du texte
<p><sup>TM</sup> 123.456.</p>
Je reçois des résultats dans android
TM 123.456.
Vous pouvez facilement afficher du texte dans Textview android avec
Html.fromText("YOUR_STRING_INHTML");
J'espère que ça aide.
J'ai implémenté ceci dans une de mes applications.
<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" />
En Activité / Frgament.Classe
myTextView = (TextView) view.findViewById(R.id.txt_formatted_value);
Codé en dur à des fins de test,
String numberValue = "123.456";
myTextView.setText(UtilityClass.getFormattedSpannedString("RM"+numberValue,
numberValue.length(),0));
Ajoutez cette classe dans votre paquet,
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);
}
}
A créé la méthode de format dans UntilityClass.Classe
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;
}
En utilisant cette méthode, vous pouvez faire plus de cirque comme changer le style de texte, la couleur séparément pour L'exposant. Vous pouvez également ajouter un exposant à droite et à gauche.(Ici, j'ai commenté tout le code, si vous voulez pouvez donner un essai...)
Vous devez utiliser la balise html comme ci-dessous pour l'indice et superscript.It fonctionne comme un charme.
((TextView) findViewById(R.id.text)).setText(Html.fromHtml("<sup><small>2</small></sup>X"));
Ou
Vous pouvez également utiliser le code ci-dessous:
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);
Classe pour top align qui devrait être utilisé à la place de RelativeSizeSpan (pas en plus de):
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);
}
}
Et utilisation:
spannableString.setSpan(new TopRelativeSizeSpan(0.50f), 0, index, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
textView.setText(spannableString, TextView.BufferType.SPANNABLE);