The usage of various Spans in Android

The usage of various Spans in Android

前言
SpannableStringBuilder
URLSpan
UnderlineSpan
TypefaceSpan
TextAppearanceSpan
TabStopSpanStandard
SuperscriptSpan
SubscriptSpan
StrikethroughSpan
ScaleXSpan
StyleSpan
RelativeSizeSpan
QuoteSpan
MaskFilterSpan
LeadingMarginSpanStandard
ImageSpan
IconMarginSpan
ForegroundColorSpan
DrawableMarginSpan
BulletSpan
BackgroundColorSpan
AlignmentSpanStandard
AbsoluteSizeSpan
ClickableSpan

source code

Foreword
Under the android.text.style package, there are some Span classes that can provide us with some special content in TextView. (For example: some content colors, fonts, sizes are different, etc., and some fonts are clickable.)

There is also a SpannableStringBuilder that helps us set up Span.

There are also all the source code below.

SpannableStringBuilder
SpannableStringBuilder can facilitate us to better set the corresponding Span.

设置Span
SpannableStringBuilder.setSpan(Object what, int start, int end, int flags)

The Flag here means: whether start and end are open or closed.

Flag:


Spanned.SPAN_EXCLUSIVE_EXCLUSIVE —— (a,b)

Spanned.SPAN_EXCLUSIVE_INCLUSIVE —— (a,b]

Spanned.SPAN_INCLUSIVE_EXCLUSIVE —— [a,b)

Spanned.SPAN_INCLUSIVE_INCLUSIVE —— [a,b]

URLSpan
function: Click on the text to open a URL.

URLSpan(String url)

SpannableStringBuilder ssb = new SpannableStringBuilder(content);
ssb.setSpan(new URLSpan("https://github.com/CaMnter"), start, sub.length(), Spanned.SPAN_INCLUSIVE_INCLUSIVE);
contentTV.setText(ssb);
// 在单击链接时凡是有要执行的动作,都必须设置MovementMethod对象
contentTV.setMovementMethod(LinkMovementMethod.getInstance());
// 设置点击后的颜色,这里涉及到ClickableSpan的点击背景
contentTV.setHighlightColor(0xff8FABCC);
URLSpan

UnderlineSpan
function: Set the text underline.

UnderlineSpan()

SpannableStringBuilder ssb = new SpannableStringBuilder(content);
ssb.setSpan(new UnderlineSpan(), start, start + sub.length(), Spanned.SPAN_INCLUSIVE_INCLUSIVE);
contentTV.setText(ssb);
UnderlineSpan

TypefaceSpan
function: Set the text font.

The comments in the source code of the TypefaceSpan(String family) constructor suggest three system fonts:

monospace

serif

sans-serif

/**
 * @param family The font family for this typeface.  Examples include
 * "monospace", "serif", and "sans-serif".
 */
public TypefaceSpan(String family) {
    mFamily = family;
}
SpannableStringBuilder ssb = new SpannableStringBuilder(content);
ssb.setSpan(new TypefaceSpan("serif"), start, start + sub.length(), Spanned.SPAN_INCLUSIVE_INCLUSIVE);
contentTV.setText(ssb);

TypefaceSpan

TextAppearanceSpan
function: Set text font, text style (bold, italic, etc.), text color status, text underline color status, etc.

Three constructs of TextAppearanceSpan

TextAppearanceSpan(Context context, int appearance)

TextAppearanceSpan(Context context, int appearance, int colorList)

TextAppearanceSpan(String family, int style, int size,ColorStateList color, ColorStateList linkColor)

monospace

serif

sans-serif

style:

Typeface.NORMAL

Typeface.BOLD

Typeface.ITALIC

Typeface.BOLD_ITALIC

size: indicates the font size (unit: px)

SpannableStringBuilder ssb = new SpannableStringBuilder(content);
ColorStateList colorStateList = null;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
    colorStateList = this.activity.getColorStateList(R.color.selector_apperarance_span);
} else {
    try {
        colorStateList = ColorStateList.createFromXml(this.activity.getResources(), this.activity.getResources().getXml(R.color.selector_apperarance_span));
    } catch (XmlPullParserException | IOException e) {
        e.printStackTrace();
    }
}
ssb.setSpan(new TextAppearanceSpan("serif", Typeface.BOLD_ITALIC, this.activity.getResources().getDimensionPixelSize(R.dimen.text_appearance_span), colorStateList, colorStateList), start, start + sub.length(), Spanned.SPAN_INCLUSIVE_INCLUSIVE);
contentTV.setText(ssb);

TextAppearanceSpan

TabStopSpan.Standard
function: the offset of MarginLeft of each line (related to \t and \n).

TabStopSpan.Standard(int where)

SpannableStringBuilder ssb = new SpannableStringBuilder(content);
String[] subs = content.split(" ");
ssb = new SpannableStringBuilder();
/**
 * TabStopSpan. Standard related to \t and \n
 * TabStopSpan.Standard 跟 \t 和 \n 有关系
 */
for (String sub1 : subs) {
    ssb.append("\t").append(sub1).append(" ");
    ssb.append("\n");
}
ssb.setSpan(new TabStopSpan.Standard(126), 0, ssb.length(), Spanned.SPAN_INCLUSIVE_INCLUSIVE);
contentTV.setText(ssb);

TabStopSpan.Standard

SuperscriptSpan
function: The text is set to superscript, which is used in mathematical formulas.

SuperscriptSpan(Parcel src)

SpannableStringBuilder ssb = new SpannableStringBuilder(content);
ssb.replace(start, start + sub.length(), "Save6");
Parcel parcel = Parcel.obtain();
parcel.writeInt(6);
int sixPosition = ssb.toString().indexOf("6");
ssb.setSpan(new SuperscriptSpan(parcel), sixPosition, sixPosition + 1, Spanned.SPAN_INCLUSIVE_INCLUSIVE);
parcel.recycle();
contentTV.setText(ssb);

SuperscriptSpan

SubscriptSpan
function: The text is set as a subscript, which is used in the chemical formula.

SubscriptSpan(Parcel src)

SpannableStringBuilder ssb = new SpannableStringBuilder(content);
ssb.replace(start, start + sub.length(), "Save6");
Parcel parcel = Parcel.obtain();
parcel.writeInt(6);
int sixPosition = ssb.toString().indexOf("6");
ssb.setSpan(new SubscriptSpan(parcel), sixPosition, sixPosition + 1, Spanned.SPAN_INCLUSIVE_INCLUSIVE);
parcel.recycle();
contentTV.setText(ssb);

SubscriptSpan

StrikethroughSpan
function: Text setting strikethrough.

StrikethroughSpan()

SpannableStringBuilder ssb = new SpannableStringBuilder(content);
ssb.setSpan(new StrikethroughSpan(), start, start + sub.length(), Spanned.SPAN_INCLUSIVE_INCLUSIVE);
contentTV.setText(ssb);

StrikethroughSpan

ScaleXSpan
function: The text is scaled horizontally.

ScaleXSpan(float proportion)

proportion: zoom ratio

SpannableStringBuilder ssb = new SpannableStringBuilder(content);
ssb.setSpan(new ScaleXSpan(2.0f), start, start + sub.length(), Spanned.SPAN_INCLUSIVE_INCLUSIVE);
contentTV.setText(ssb);

ScaleXSpan

StyleSpan
function: Text setting style (normal, bold, italic, bold italic).

StyleSpan(int style)

style:

Typeface.NORMAL

Typeface.BOLD

Typeface.ITALIC

Typeface.BOLD_ITALIC

SpannableStringBuilder ssb = new SpannableStringBuilder(content);
ssb.setSpan(new StyleSpan(Typeface.BOLD_ITALIC), start, start + sub.length(), Spanned.SPAN_INCLUSIVE_INCLUSIVE);
contentTV.setText(ssb);

StyleSpan

RelativeSizeSpan
function: Set the relative size of the text, which refers to the relative ratio relative to the size set by the text.

RelativeSizeSpan(float proportion)

proportion: size ratio.

SpannableStringBuilder ssb = new SpannableStringBuilder(content);
ssb.setSpan(new RelativeSizeSpan(6.0f), start, start + sub.length(), Spanned.SPAN_INCLUSIVE_INCLUSIVE);
contentTV.setText(ssb);

RelativeSizeSpan

QuoteSpan
function: Set the quotation style (a vertical line) to be displayed on the left side of the text.

QuoteSpan(@ColorInt int color)

color: The color of the vertical line.

SpannableStringBuilder ssb = new SpannableStringBuilder(content);
ssb.setSpan(new QuoteSpan(0xff000000), start, start + sub.length(), Spanned.SPAN_INCLUSIVE_INCLUSIVE);
contentTV.setText(ssb);

QuoteSpan

MaskFilterSpan
function: Set the text blur effect and relief effect.

MaskFilterSpan(MaskFilter filter)

MaskFilter:

BlurMaskFilter: Blur effect

EmbossMaskFilter: Emboss effect

SpannableStringBuilder ssb = new SpannableStringBuilder(content);
MaskFilterSpan embossMaskFilterSpan = new MaskFilterSpan(new EmbossMaskFilter(new float[]{3, 3, 9}, 3.0f, 12, 16));
ssb.setSpan(embossMaskFilterSpan, start, start + sub.length(), Spanned.SPAN_INCLUSIVE_INCLUSIVE);
contentTV.setText(ssb);
String you = "you";
int indexYou = content.indexOf(you);
MaskFilterSpan blurMaskFilterSpan = new MaskFilterSpan(new BlurMaskFilter(3, BlurMaskFilter.Blur.OUTER));
ssb.setSpan(blurMaskFilterSpan, indexYou, indexYou + you.length(), Spanned.SPAN_INCLUSIVE_INCLUSIVE);
contentTV.setText(ssb);

MaskFilterSpan

LeadingMarginSpan.Standard
function: Set the text indent.

LeadingMarginSpan.Standard(int first, int rest)

first: the margin left offset of the first row.
rest: margin left offset of other rows.

SpannableStringBuilder ssb = new SpannableStringBuilder(content);
ssb.append(" ")
        .append(ssb.toString())
        .append(ssb.toString())
        .append(ssb.toString());
ssb.setSpan(new LeadingMarginSpan.Standard(96, 36), 0, ssb.length(), Spanned.SPAN_INCLUSIVE_INCLUSIVE);
contentTV.setText(ssb);

LeadingMarginSpan.Standard

ImageSpan
function: Insert text into pictures.

There are many construction methods:

ImageSpan(Context context, Bitmap b)

ImageSpan(Context context, Bitmap b, int verticalAlignment)

ImageSpan(Drawable d)

ImageSpan(Drawable d, int verticalAlignment)

ImageSpan(Drawable d, String source)

ImageSpan(Drawable d, String source, int verticalAlignment)

ImageSpan(Context context, Uri uri)

ImageSpan(Context context, Uri uri, int verticalAlignment)

ImageSpan(Context context, @DrawableRes int resourceId)

ImageSpan(Context context, @DrawableRes int resourceId, int verticalAlignment)

verticalAlignment:

ImageSpan.ALIGN_BOTTOM

ImageSpan.ALIGN_BASELINE

source: The native path String of the image. ( xxx/xxx/xxx.jpg )

uri: The native uri of the image.

SpannableStringBuilder ssb = new SpannableStringBuilder(content);
ssb.replace(start, start + sub.length(), " Save");
ssb.setSpan(new ImageSpan(this.activity, R.mipmap.ic_mm_1, ImageSpan.ALIGN_BASELINE), 0, 1, Spanned.SPAN_INCLUSIVE_INCLUSIVE);
contentTV.setText(ssb);

ImageSpan

IconMarginSpan
function: text insertion picture + Margin.

IconMarginSpan(Bitmap b, int pad)

pad: margin offset.

SpannableStringBuilder ssb = new SpannableStringBuilder(content);
Bitmap bitmap = BitmapFactory.decodeResource(this.activity.getResources(), R.mipmap.ic_mm_1);
ssb.setSpan(new IconMarginSpan(bitmap, 60), 0, 1, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
//bitmap.recycle();
contentTV.setText(ssb);

IconMarginSpan

ForegroundColorSpan
function: Set the text color.

ForegroundColorSpan(@ColorInt int color)

SpannableStringBuilder ssb = new SpannableStringBuilder(content);
ssb.setSpan(new ForegroundColorSpan(0xff303F9F), start, start + sub.length(), Spanned.SPAN_INCLUSIVE_INCLUSIVE);
contentTV.setText(ssb);

ForegroundColorSpan

DrawableMarginSpan
function: insert text into picture + Margin.

DrawableMarginSpan(Drawable b, int pad)

pad: margin offset.

SpannableStringBuilder ssb = new SpannableStringBuilder(content);
ssb.setSpan(new DrawableMarginSpan(ResourcesUtil.getDrawable(this.activity, R.mipmap.ic_mm_1), 6), 0, 1, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
contentTV.setText(ssb);

DrawableMarginSpan

BulletSpan
function: similar to in HTML

  • Dot effect for labels.
  • BulletSpan(int gapWidth, int color)

    gapWidth: The distance between the dot and the text.

    color: Dot color.

    SpannableStringBuilder ssb = new SpannableStringBuilder(content);
    ssb.setSpan(new BulletSpan(66, 0xff303F9F), start, start + sub.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
    contentTV.setText(ssb);

    BulletSpan

    BackgroundColorSpan
    function: Set the background color.

    BackgroundColorSpan(int color)

    SpannableStringBuilder ssb = new SpannableStringBuilder(content);
    String you = "you";
    int indexYou = content.indexOf(you);
    ssb.setSpan(new BackgroundColorSpan(0x2f303F9F), start, start + sub.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
    ssb.setSpan(new BackgroundColorSpan(0x2fFF4081), indexYou, indexYou + you.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
    contentTV.setText(ssb);

    BackgroundColorSpan

    AlignmentSpan.Standard
    function: Set the text alignment.

    AlignmentSpan.Standard(Layout.Alignment align)

    align:

    Layout.Alignment.ALIGN_NORMAL

    Layout.Alignment.ALIGN_OPPOSITE

    Layout.Alignment.ALIGN_CENTER

    Layout.Alignment.ALIGN_LEFT

    Layout.Alignment.ALIGN_RIGHT

    SpannableStringBuilder ssb = new SpannableStringBuilder(content);
    ssb.setSpan(new AlignmentSpan.Standard(Layout.Alignment.ALIGN_CENTER), 0, ssb.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
    contentTV.setText(ssb);

    AbsoluteSizeSpan
    function: Set the absolute size of the text.

    AbsoluteSizeSpan(int size, boolean dip)

    size: The default unit is px.
    dip: true is the size unit is dip, false is px.

    SpannableStringBuilder ssb = new SpannableStringBuilder(content);
    ssb.setSpan(new AbsoluteSizeSpan(26, true), start, start + sub.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
    contentTV.setText(ssb);

    AbsoluteSizeSpan

    ClickableSpan
    function: the text can be clicked.

    Abstract class, you need to extend the implementation yourself.

    ClickableSpanNoUnderline

    public class ClickableSpanNoUnderline extends ClickableSpan {
    
        private static final String TAG = "ClickableSpan";
    
        private static final int NO_COLOR = -206;
        private int color;
    
        private OnClickListener onClickListener;
    
        public ClickableSpanNoUnderline(int color, OnClickListener onClickListener) {
            super();
            this.color = color;
            this.onClickListener = onClickListener;
        }
    
        public ClickableSpanNoUnderline(OnClickListener onClickListener) {
            this(NO_COLOR, onClickListener);
        }
    
        /**
         * Makes the text underlined and in the link color.
         *
         * @param ds
         */
        @Override
        public void updateDrawState(@NonNull TextPaint ds) {
            super.updateDrawState(ds);
            // 设置文字颜色
            if (this.color == NO_COLOR) {
                ds.setColor(ds.linkColor);
            } else {
                ds.setColor(this.color);
            }
            ds.clearShadowLayer();
            // 去除下划线
            ds.setUnderlineText(false);
            ds.bgColor = Color.TRANSPARENT;
        }
    
        /**
         * Performs the click action associated with this span.
         *
         * @param widget widget
         */
        @Override
        public void onClick(View widget) {
            if (this.onClickListener != null) {
                this.onClickListener.onClick(widget, this);
            } else {
                Log.w(TAG, "listener was null");
            }
        }
    
        /**
         * 回调接口,回调自身的onClick事件
         * 告诉外部 是否被点击
         */
        public interface OnClickListener<T extends ClickableSpanNoUnderline> {
            /**
             * ClickableSpan被点击
             *
             * @param widget widget
             * @param span   span
             */
            void onClick(View widget, T span);
        }
    
    }

    SpanClickableSpan

    private class SpanClickableSpan extends ClickableSpanNoUnderline {
    
        private String urlString;
    
        public String getUrlString() {
            return urlString;
        }
    
        public void setUrlString(String urlString) {
            this.urlString = urlString;
        }
    
        public SpanClickableSpan(int color, OnClickListener onClickListener) {
            super(color, onClickListener);
        }
    
        public SpanClickableSpan(OnClickListener onClickListener) {
            super(onClickListener);
        }
    
    }

    start using

    SpannableStringBuilder ssb = new SpannableStringBuilder(content);
    SpanClickableSpan spanClickableSpan = new SpanClickableSpan(0xffFF4081, new ClickableSpanNoUnderline.OnClickListener<SpanClickableSpan>() {
        /**
         * ClickableSpan被点击
         *
         * @param widget widget
         * @param span   span
         */
        @Override
        public void onClick(View widget, SpanClickableSpan span) {
            String urlString = span.getUrlString();
            if (TextUtils.isEmpty(urlString)) return;
            Uri uri = Uri.parse(urlString);
            Context context = widget.getContext();
            Intent intent = new Intent(Intent.ACTION_VIEW, uri);
            intent.putExtra(Browser.EXTRA_APPLICATION_ID, context.getPackageName());
            try {
                context.startActivity(intent);
            } catch (ActivityNotFoundException e) {
                Log.w("URLSpan", "Activity was not found for intent, " + intent.toString());
            }
        }
    });
    spanClickableSpan.setUrlString("https://github.com/CaMnter");
    ssb.setSpan(spanClickableSpan, start, start + sub.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
    contentTV.setText(ssb);
    // 在单击链接时凡是有要执行的动作,都必须设置MovementMethod对象
    contentTV.setMovementMethod(LinkMovementMethod.getInstance());
    // 设置点击后的颜色,这里涉及到ClickableSpan的点击背景
    contentTV.setHighlightColor(0x00000000);

    ClickableSpan

    source code

    Guess you like

    Origin http://43.154.161.224:23101/article/api/json?id=324839275&siteId=291194637