Spannable TextView

可以在 Android 中使用 spanhable TextView 来突出显示单个 TextView 小部件中具有不同颜色,样式,大小和/或单击事件的文本的特定部分。

考虑一下你已经定义了一个 TextView 如下:

TextView textview=findViewById(R.id.textview);

然后你可以对其应用不同的突出显示,如下所示:

  • 可跨越颜色: 为了为文本的某些部分设置不同的颜色,可以使用 ForegroundColorSpan,如下例所示:

    Spannable spannable = new SpannableString(firstWord+lastWord);
    spannable.setSpan(new ForegroundColorSpan(firstWordColor), 0, firstWord.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
    spannable.setSpan(new ForegroundColorSpan(lastWordColor), firstWord.length(), firstWord.length()+lastWord.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
    textview.setText( spannable );
    

    上面代码创建的输出:

    StackOverflow 文档

  • Spannable 字体: 为了为文本的某些部分设置不同的字体大小,可以使用 RelativeSizeSpan,如下例所示:

    Spannable spannable = new SpannableString(firstWord+lastWord);
    spannable.setSpan(new RelativeSizeSpan(1.1f),0, firstWord.length(),  Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); // set size
    spannable.setSpan(new RelativeSizeSpan(0.8f), firstWord.length(), firstWord.length() + lastWord.length(),  Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); // set size
    textview.setText( spannable );
    

    上面代码创建的输出:

    StackOverflow 文档

  • Spannable 字体: 为了为文本的某些部分设置不同的字体字体,可以使用自定义 TypefaceSpan,如以下示例所示:

    Spannable spannable = new SpannableString(firstWord+lastWord);
    spannable.setSpan( new CustomTypefaceSpan("SFUIText-Bold.otf",fontBold), 0, firstWord.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
    spannable.setSpan( new CustomTypefaceSpan("SFUIText-Regular.otf",fontRegular), firstWord.length(), firstWord.length() + lastWord.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
    text.setText( spannable );
    

    但是,为了使上述代码有效,类 CustomTypefaceSpan 必须从类 TypefaceSpan 派生。这可以按如下方式完成:

    public class CustomTypefaceSpan extends TypefaceSpan {
        private final Typeface newType;
    
        public CustomTypefaceSpan(String family, Typeface type) {
            super(family);
            newType = type;
        }
    
        @Override
        public void updateDrawState(TextPaint ds) {
            applyCustomTypeFace(ds, newType);
        }
    
        @Override
        public void updateMeasureState(TextPaint paint) {
            applyCustomTypeFace(paint, newType);
        }
    
        private static void applyCustomTypeFace(Paint paint, Typeface tf) {
            int oldStyle;
            Typeface old = paint.getTypeface();
            if (old == null) {
                oldStyle = 0;
            } else {
                oldStyle = old.getStyle();
            }
            int fake = oldStyle & ~tf.getStyle();
            if ((fake & Typeface.BOLD) != 0) {
                paint.setFakeBoldText(true);
            }
    
            if ((fake & Typeface.ITALIC) != 0) {
                paint.setTextSkewX(-0.25f);
            }
    
            paint.setTypeface(tf);
        }
    }