Exploring Android Rich Text SpannableStringBuilder

Article directory

  • foreword
  • 1. What is SpannableStringBuilder?
  • 2. Use steps
    • 1. Sample code
    • 2. Parameter correspondence
      • start: The starting position where the style takes effect, including this position
      • end: The position where the style ends, not including this position
      • flags: There are four values as follows
        • Spannable. SPAN_EXCLUSIVE_INCLUSIVE
        • Spannable. SPAN_INCLUSIVE_EXCLUSIVE
        • Spannable.SPAN_INCUJSIVE_INCLUSIVE
        • Spannable. SPAN_EXCLUSIVE_EXCLUSIVE
      • what: the corresponding Span
            • 1 BackgroundColorSpan : background color
            • 2 ForegroundColorSpan : color
            • 3 RasterizerSpan : raster
            • 4 StrikethroughSpan : StrikethroughSpan
            • 5 SuggestionSpan : placeholder
            • 6 UnderlineSpan : underline
            • 7 AbsoluteSizeSpan : text font
            • 8 ImageSpan : Image
            • 9 ScaleXSpan : Horizontal scaling based on the x-axis text
            • 10 StyleSpan : font style: bold, italic, etc.
            • 11 SubscriptSpan : subscript
            • 12 SuperscriptSpan : superscript
            • 13 TypefaceSpan : font style
            • 14 URLSpan : hyperlink
            • 15 ClickableSpan : click event
            • 16 AbsoluteSizeSpan font size
    • 3.SpannableStringBuilder basic style example
            • 1 bold
            • 2 italics
            • 3 Bold and italic
            • 4 strikethrough
            • 5 underscores
            • 6 font colors
            • 7 background colors
            • 8 text size
            • 9 hyperlinks
            • 10 pictures
            • 11 Text scaling horizontally
            • 12 font styles
            • 13 row height
            • 14 character spacing
  • 3. SpannableStringBuilder custom style
          • Custom span text blur
          • Custom span text background color
          • Custom span text shadow
          • Custom span text stroke
  • Summarize

Foreword

Why do we talk about the SpannableStringBuilder class today? This starts from the previous sad project experience. The prototype looks like this. We mainly look at the text and ignore the rest for the time being.
When you see the picture, do you feel familiar, because it is a terms of service and privacy The policy is the same as the check submit function. If there is no accident, the TextView text splicing, and then add the click event to jump, you’re done, but often there will be accidents at this time. This service term is very privacy policy. The interface is dynamically obtained, and it may be It could be one or two, but at this point, isn’t it amazing that I can tell you that one TextView can do it all? Let’s take a look at the final implementation effect of this chapter

Demo source code is at the bottom of the article, Star or Fork is welcome

1. What is SpannableStringBuilder?

Google’s official introduction is already very straightforward. The translation is that this is a class for text that can be changed both in content and markup. Did you think of rich text for the first time? Yes, it is the class used to create rich text in Android. It is an implementation class of the Spannable interface, which can add styles, pictures, hyperlinks and other effects to the text.

Similar to StringBuilder, SpannableStringBuilder is also a dynamic string class that supports inserting and deleting text, but it can add various styles to the text,

We can know from the source code that SpannableStringBuilder mainly implements the CharSequence and Spannable interfaces.
CharSequence interface is a character sequence interface defined in Java, which represents a character sequence, which can be Is String, StringBuilder, StringBuffer and other types. The CharSequence interface is a read-only interface that provides the following methods:

charAt(int index): returns the character at the specified position.
length(): Returns the length of the character sequence.
subSequence(int start, int end): Returns the character sequence subsequence from start to end-1.
toString(): Returns the string representation of a character sequence.

The role of the CharSequence interface is to realize the polymorphism of character sequences. By implementing this interface, different character sequence types can use the same method, which facilitates programming and improves code readability. For example, when a method expects a parameter of type CharSequence, an object of any class that implements the CharSequence interface can be passed.

In Android, the CharSequence interface is widely used. Using the CharSequence interface can make the program more flexible and improve the reusability of the code.

Then look at the Spannable interface, which is translated by annotations as the interface that marks the text that the object can point to. The Spannable interface defines methods for adding, removing, and obtaining rich text styles,

setSpan(Object what, int start, int end, int flags): Add a style what to the text between start and end, the flags parameter is used to control the behavior of the style.

removeSpan(Object what): Removes the specified style what from the text.

getSpans(int start, int end, Class<T> type): Get all styles of type type in the text between start and end.

Many application scenarios can be realized by using the Spannable interface, such as: rich text editor, emoticons in chat applications, highlighted search keywords, etc. It can help programmers achieve better user interaction experience and improve the quality and usability of applications.

Finally, let’s look at the two main methods, which provide rich text

public SpannableStringBuilder append(CharSequence text) {}

The function of this method is to append a character sequence text to the end of the SpannableStringBuilder instance and return the appended SpannableStringBuilder object
public void setSpan(Object what, int start, int end, int flags) {}

Known through translation
Marks the specified range of text with the specified object. flag determines when text is . Insert at the beginning or end of the span range.

2. Steps to use

1. Sample code

 SpannableStringBuilder builder1 = new SpannableStringBuilder();
        builder1.append("Hello World ! Do you like programming?"); // add normal text
        builder1.setSpan(new StyleSpan(Typeface.BOLD), 0, 5, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); // bold
        builder1.setSpan(new ForegroundColorSpan(Color.RED), 6, 11, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); // font color
        builder1.setSpan(new UnderlineSpan(), 12, 17, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); // underline
        builder1.setSpan(new URLSpan("https://www.baidu.com"), 18, 28, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); // hyperlink
        builder1.setSpan(new ImageSpan(this, R.mipmap.icon_pair_number), 29, 34, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); // image
        span1Tv.setText(builder1);

2. Parameter correspondence

start: the starting position where the style takes effect, including this position

end: The position where the style ends, not including this position

 Note: Set the style of the first 2 characters of the string to start:0,end:2. instead of end:1

flags: There are four values as follows

Spannable. SPAN_EXCLUSIVE_INCLUSIVE

 Does not include before, includes after, the character input before the span does not apply the span effect, and the character input after the span applies the span effect.

Spannable. SPAN_INCLUSIVE_EXCLUSIVE

 Include before, not after, that is, inserting new text before the text will apply the style, but inserting new text after the text will not apply the style

Spannable. SPAN_INCUJSIVE_INCLUSIVE

 Include before, include after, that is, inserting new text before the text will apply the style, and inserting new text after the text will also apply the style

Spannable. SPAN_EXCLUSIVE_EXCLUSIVE

 does not include before, does not include after, the effect of span is not applied before and after the characters entered before and after Span

what: the corresponding Span

1 BackgroundColorSpan : background color
2 ForegroundColorSpan : Color
3 RasterizerSpan : Raster
4 StrikethroughSpan : strikethrough
5 SuggestionSpan : placeholder
6 UnderlineSpan: Underline
7 AbsoluteSizeSpan : text font
8 ImageSpan : Image
9 ScaleXSpan: horizontal scaling based on the x-axis text
10 StyleSpan: font style: bold, italic, etc.
11 SubscriptSpan: Subscript
12 SuperscriptSpan : Superscript
13 TypefaceSpan: font style
14 URLSpan : hyperlink
15 ClickableSpan : click event
16 AbsoluteSizeSpan font size

3.SpannableStringBuilder basic style example

1 bold
builder.setSpan(new StyleSpan(Typeface.BOLD), start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
2 italics
builder.setSpan(new StyleSpan(Typeface.ITALIC), start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
3 bold and italic
builder.setSpan(new StyleSpan(Typeface.BOLD_ITALIC), start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
4 strikethrough
builder.setSpan(new StrikethroughSpan(), start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
5 underline
builder.setSpan(new UnderlineSpan(), start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
6 font color
builder.setSpan(new ForegroundColorSpan(color), start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
7 background color
builder.setSpan(new BackgroundColorSpan(color), start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
8 text size
builder.setSpan(new AbsoluteSizeSpan(sizeInPx), start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
9 hyperlinks
builder.setSpan(new URLSpan(url), start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
10 images
builder.setSpan(new ImageSpan(context, resourceId), start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
11 Horizontal text scaling
builder.setSpan(new ScaleXSpan(scale), start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
12 font styles
builder.setSpan(new TypefaceSpan(typeface), start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
13 line height
builder.setSpan(new LineHeightSpan() {<!-- -->
    @Override
    public void chooseHeight(CharSequence text, int start, int end, int spanstartv, int v, Paint.FontMetricsInt fm) {<!-- -->
        fm.descent += lineHeight - fm.bottom;
        fm.bottom = lineHeight;
    }
}, start, end, Spannable. SPAN_EXCLUSIVE_EXCLUSIVE);
14 character spacing
builder.setSpan(new ScaleXSpan(spacing), start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);

3. SpannableStringBuilder custom style

In addition to the basic styles, you can also customize other styles, such as: text stroke, text blur, etc. Just inherit the CharacterStyle class and override the updateDrawState() method.

Custom span text blur
 In this example, we have customized a BlurSpan type to set the text blur effect. It inherits from the CharacterStyle class and overrides the updateDrawState() method, where it sets the blur effect of the text.

 In the updateDrawState() method, we first create a BlurMaskFilter object, which is used to set the blur radius and blur type. Then, we use the setMaskFilter() method to set the blur effect of the text.
/**
 * Custom span text blur
 */
public class BlurSpan extends CharacterStyle {<!-- -->

    private float mRadius;

    public BlurSpan(float radius) {<!-- -->
        this.mRadius = radius;
    }

    @Override
    public void updateDrawState(TextPaint tp) {<!-- -->
        tp.setMaskFilter(new BlurMaskFilter(mRadius, BlurMaskFilter.Blur.NORMAL));
    }
}
Custom span text background color
In this example, we have customized a CustomBackgroundColorSpan type to set the background color of the text. It inherits from the CharacterStyle class and overrides the updateDrawState() method, where it sets the background color of the text.
public class CustomSpan extends CharacterStyle {<!-- -->

    private int mBackgroundColor;

    public CustomSpan(int backgroundColor) {<!-- -->
        this.mBackgroundColor = backgroundColor;
    }

    @Override
    public void updateDrawState(TextPaint tp) {<!-- -->
        tp.bgColor = mBackgroundColor;
    }
}
Custom span text shadow
 In this example, we have customized a ShadowSpan type to set the text shadow effect. It inherits from the CharacterStyle class and overrides the updateDrawState() method, where the shadow effect of the text is set.

 In the updateDrawState() method, we first create a shadow layer whose radius, offset, and color are determined by mRadius, mDx, mDy, and mShadowColor, respectively. Then, we use the setShadowLayer() method to set the shadow effect.
public class ShadowSpan extends CharacterStyle {<!-- -->

    private float mRadius;
    private float mDx;
    private float mDy;
    private int mShadowColor;

    public ShadowSpan(float radius, float dx, float dy, int shadowColor) {<!-- -->
        this.mRadius = radius;
        this.mDx = dx;
        this.mDy = dy;
        this.mShadowColor = shadowColor;
    }

    @Override
    public void updateDrawState(TextPaint tp) {<!-- -->
        tp.setShadowLayer(mRadius, mDx, mDy, mShadowColor);
    }
}
Custom span text stroke
 In this example, we have customized a StrokeSpan type to set the text stroke effect. It inherits from the CharacterStyle class, rewrites the updateDrawState() method, and sets the stroke effect of the text in this method.

 In the updateDrawState() method, we first set the style of the text to the stroke style, and then set the stroke width and stroke color.
public class StrokeSpan extends CharacterStyle {<!-- -->

    private float mStrokeWidth;
    private int mStrokeColor;

    public StrokeSpan(float strokeWidth, int strokeColor) {<!-- -->
        this.mStrokeWidth = strokeWidth;
        this.mStrokeColor = strokeColor;
    }

    @Override
    public void updateDrawState(TextPaint tp) {<!-- -->
        tp.setStyle(Paint.Style.STROKE);
        tp.setStrokeWidth(mStrokeWidth);
        tp.setColor(mStrokeColor);
    }
}

Summary

In short, SpannableStringBuilder is a very convenient way to create rich text, allowing you to add various styles and effects to the text.

If it is helpful to you, you may wish to Star or Fork. The green mountains will not change, and the green water will flow forever. See you in the rivers and lakes~

Source address: RichTextDemo