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);
        }
    }