preface
These days, when doing requirements, there is often a text that needs to be highlighted separately, and support a separate click event for that part.
There are several ways to do this:
- Use multiple TextViews for concatenation display
- Load the Html in the TextView
- Use SpannableString/SpannableStringBuilder
The inflexibility of the first option is not considered here.
The second option is to wrap the string with HTML tags and then use html.fromhtml (STR) to get the rendered string and set it to the TextView. If you want to pop up a local popup window or jump to another Activity, you may need to implement it through JS injection.
So the most commonly used scheme is the third one. SpannableString or SpannableStringBuilder is very powerful and can make a TextView very colorful. Let’s see.
SpannableStringBuilder and SpannableString
SpannableStringBuilder and SpannableString can both be used to display rich text, just like StringBuilder and String, SpannableStringBuilder can concatenate strings, SpannableString can’t. They both implement the Spannable interface.
Span
SpannableStringBuilder setSpan(Object What, int Start, int end, int flags) setSpan(Object What, int start, int end, int flags)
Parameter Description:
Start: indicates the start position subscript. End: indicates the end position subscript
What: Various Span instances
The following table lists some of the available spans:
Span | meaning | note |
---|---|---|
BackgroundColorSpan | Sets the text background color | Pass in a color value of type int |
ForegroundColorSpan | Set the text color | Pass in a color value of type int |
ClickableSpan | Setting click events | You need to inherit this class to override the onClick method |
StrikethroughSpan | Set strikeout effect | No arguments |
UnderlineSpan | Set underline effect | No arguments |
AbsoluteSizeSpan | Sets the absolute size of the text | The first argument is the font size, in px, and the second argument, in dip, is false by default. When set to true, the first argument is dp |
RelativeSizeSpan | Sets the relative size of the text | |
StyleSpan | Set the text to bold and italic | Typeface.BOLD is in BOLD, Typeface.ITALIC is in ITALIC, and Typeface.BOLD_ITALIC is in BOLD ITALIC |
ImageSpan | Set the picture | Replaces the text in the [start,end) range with the picture passed in as the parameter |
MaskFilterSpan | Embellish effects, such as BlurMaskFilter emboss | |
RasterizerSpan | Effect of grating | |
SuggestionSpan | It’s a placeholder | |
DynamicDrawableSpan | Set images based on text baseline or bottom alignment | |
ScaleXSpan | Scale on the x axis | |
SubscriptSpan | Subscripts (used in mathematical formulas) | |
SuperscriptSpan | Superscripts (used in mathematical formulas) | |
TextAppearanceSpan | Text appearance (including font, size, style, and color) | |
TypefaceSpan | The text font | |
URLSpan | Text hyperlink |
Flag: the value can be four
flag | meaning |
---|---|
SPAN_EXCLUSIVE_EXCLUSIVE | This style is not applied when new text is inserted before or after the text (not included before, not included after) |
SPAN_EXCLUSIVE_INCLUSIVE | Inserting new text before text does not apply the style, while inserting new text after text applies the style (not included before, included after) |
SPAN_INCLUSIVE_EXCLUSIVE | Inserting new text in front of text applies the style, but inserting new text after text does not. |
SPAN_INCLUSIVE_INCLUSIVE | This style is applied whenever new text is inserted before or after the text (included before, included after) |
A. EXCLUSIVE B. INCLUSIVE C. EXCLUSIVE D. EXCLUSIVE Most use the first one, neither before nor after.
The sample
A simple example is made of a few of the commonly used Spans. The code is as follows:
class SpannableAcitivity : AppCompatActivity() {
val textStr = "Stay up late to listen to the wind and rain, iron horse ice Falls asleep."
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_spannable)
var builder = SpannableStringBuilder().also {
it.append(textStr)
it.setSpan(ForegroundColorSpan(Color.BLUE), 0, 1, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
it.setSpan(BackgroundColorSpan(Color.RED), 1, 3, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
it.setSpan(object : ClickableSpan() {
override fun onClick(widget: View) {
Toast.makeText(this@SpannableAcitivity, "Listen to the wind and rain.", Toast.LENGTH_SHORT).show()
}
}, 3, 7, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
it.setSpan(StrikethroughSpan(), 8, 9, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
it.setSpan(UnderlineSpan(), 9, 10, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
it.setSpan(AbsoluteSizeSpan(50), 10, 11, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
it.setSpan(StyleSpan(Typeface.BOLD), 11, 12, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
it.setSpan(ImageSpan(this@SpannableAcitivity, R.mipmap.ic_launcher),
12, 13, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
}
spannable_tv.text = builder
spannable_tv.movementMethod = LinkMovementMethod.getInstance()
}
}
Copy the code
The effect is as follows:
ClickableSpan note
When using ClickableSpan, note the following:
- There are default colors and sliders, so if you want to change the colors or get rid of underscores, you need to override the updateDrawState method.
@Override public void updateDrawState(@NonNull TextPaint ds) {
super.updateDrawState(ds);
ds.setColor(getResources().getColor(R.color.color_black));
ds.setUnderlineText(false);
}
Copy the code
-
After setting ClickableSpan TextView lines need to add a TextView. SetMovementMethod (LinkMovementMethod. GetInstance ()); Otherwise the ClickableSpan partial click event will not work.
-
Setting ClickableSpan may conflict with the onClick event of the TextView itself.
The resources
Android-textview sets multiple colors and partial click events
[Android] Powerful SpannableStringBuilder