如何使RelativeSizeSpan与顶部对齐

Che*_*eng 34 android spannablestring android-studio

我有以下字符串RM123.456.我想要

  • 使RM相对较小
  • RM准确对齐

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

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

结果看起来像

在此输入图像描述

但是,它与底部对齐.它没有与顶部对齐.

我试着用SuperscriptSpan.看起来像

在此输入图像描述

它没有做我想要的

  • SuperscriptSpan不会使文字变小.我无法控制其尺寸.
  • SuperscriptSpan 将使文本"在顶部对齐"

我可以知道,我怎样才能让RelativeSizeSpan 准确对齐?

这就是我希望实现的目标.

在此输入图像描述

请注意,我们不希望使用2 TextViews解决方案.

Hir*_*tel 22

但是我这样做了:

在此输入图像描述

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" />
Run Code Online (Sandbox Code Playgroud)

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);
Run Code Online (Sandbox Code Playgroud)

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 );
        }
    }
Run Code Online (Sandbox Code Playgroud)

希望这会帮助你.

  • 但是,这仍然没有对齐。您可以看到“RM”的位置高于“123.456” (2认同)

tyn*_*ynn 13

我看了一下,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;
    }
}
Run Code Online (Sandbox Code Playgroud)


Abh*_*k V 10

您可以通过创建自定义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);
    }
}
Run Code Online (Sandbox Code Playgroud)

应用跨度:

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);
Run Code Online (Sandbox Code Playgroud)

输出:

在此输入图像描述

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

Custom MetricAffectingSpan逻辑引用自:单个textview中的两种不同样式,具有不同的重力和高度


Sri*_*san 9

我在我的一个应用程序中实现了这一点.

 <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" />
Run Code Online (Sandbox Code Playgroud)

在Activity/Frgament.class中

 myTextView = (TextView) view.findViewById(R.id.txt_formatted_value);
Run Code Online (Sandbox Code Playgroud)

硬编码用于测试目的,

String numberValue = "123.456";    
myTextView.setText(UtilityClass.getFormattedSpannedString("RM"+numberValue,
     numberValue.length(),0));
Run Code Online (Sandbox Code Playgroud)

在您的包中添加此类,

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);
}
Run Code Online (Sandbox Code Playgroud)

}

在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;
}
Run Code Online (Sandbox Code Playgroud)

使用此方法,您可以为SuperScript分别更改文本样式和颜色等马戏团.你也可以在左右两边添加上标.(这里我评论了所有代码,如果你想要试试......)

在此输入图像描述在此输入图像描述在此输入图像描述


Imt*_*ani 8

最合适的解决方案是使用html.

我更喜欢这个解决方案,它支持所有Android版本以及设备.

这里的例子就像你想要的文字一样

<p><sup>TM</sup> 123.456.</p>
Run Code Online (Sandbox Code Playgroud)

我在android中得到了结果

TM 123.456.

你可以在android中的Textview中轻松显示文本

Html.fromText("YOUR_STRING_INHTML");

希望能帮助到你.


Dar*_*try 6

你必须使用下面的html标签作为下标和上标.它就像魅力一样.

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

在此输入图像描述

要么

您还可以使用以下代码:

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);
Run Code Online (Sandbox Code Playgroud)