1, Foreword
Recently, we encountered such a problem when designing the interface. We can often see such an interface, which tells users the privacy terms and user agreement, and these color words directly point to the corresponding links
At that time, the original idea was to set up multiple textviews to realize it. However, there would be a problem. Such a simple function uses five controls, which is too embarrassing. Moreover, the text alignment needs to be adjusted by itself. It is unnatural. After searching, the implementation method is not difficult, but there is no better encapsulation, So today I'll show you how to encapsulate a colorText method with kotlin's extension function. I have to praise kotlin's extension function, which is really easy to use.
2, Design click event
First, you need to create a container for SpannableStringBuilder to apply click events and so on
val style = SpannableStringBuilder() val parent = "I have read and agree to the user agreement and privacy policy" val colorText = "User agreement" //Find the subscript of the first colorText val index = indexOf(colorText,0) style.append(parent)
Then let's set the click event
//It is equivalent to overriding the method of a click event in an anonymous class val clickableSpan = object : ClickableSpan(){ override fun onClick(widget: View) { //Specific events } } //The first parameter is the option to set the click event, the second is the position of colorText in the parent, the second is the position of the last text, and the third is a fixed parameter style.setSpan(clickableSpan, index, index+colorText.length, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
So far, the current colorText has the click of events
3, Set no underline
This part is also very important. You added an inexplicable underline without setting your text
First, you need to create a class to make an underline
class NoUnderlineSpan: UnderlineSpan(){ override fun updateDrawState(ds: TextPaint) { super.updateDrawState(ds) ds.color = ds.linkColor ds.isUnderlineText = false } }
Finally, set it
//The parameters here are similar to those in the previous one. The first one is to set no underline. 2 and 3 are the same as above. The fourth option is replaced val noUnderlineSpan = NoUnderlineSpan() style.setSpan(noUnderlineSpan,index , index+colorText.length, Spanned.SPAN_MARK_MARK)
4, Set color
Set the color of the link. This part is similar to the above. Set the foreground color. Other parameters are similar
val foregroundColorSpan = ForegroundColorSpan(Color.parseColor("#118EEA")) style.setSpan(foregroundColorSpan, index, index+colorText.length, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
Finally, you need to apply it to realize the click event of color link
MyTextView.movementMethod = LinkMovementMethod.getInstance() MyTextView.text = style
5, Encapsulation
After talking about it in parts, the next step is the most wonderful encapsulation, which uses Kotlin's extension function
- First, analyze that the class to be extended is TextView class. In this way, any control that inherits TextView class can use the function of this extension function
- Secondly, analyze the required parameters, which should be functional parameters that require complete text, colorText, colorString and click events. Later, think about it wrong. You already have its context in TextView and can directly obtain the complete text. Therefore, finally, you need three parameters, colorText, colorString and functional parameters
The following is the final package. It looks very long, but it is very convenient to use
//The text may not be found here. If an error occurs, remember to check whether the text is correct class NoUnderlineSpan: UnderlineSpan(){ override fun updateDrawState(ds: TextPaint) { super.updateDrawState(ds) ds.color = ds.linkColor ds.isUnderlineText = false } } fun TextView.colorText(colorText:String, color:String, click:()->Unit){ val style = SpannableStringBuilder() val index = text.indexOf(colorText,0) style.append(text) val clickableSpan = object : ClickableSpan(){ override fun onClick(widget: View) { click() } } style.setSpan(clickableSpan, index, index+colorText.length, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE) val noUnderlineSpan = NoUnderlineSpan() style.setSpan(noUnderlineSpan,index , index+colorText.length, Spanned.SPAN_MARK_MARK) val foregroundColorSpan = ForegroundColorSpan(Color.parseColor(color)) style.setSpan(foregroundColorSpan, index, index+colorText.length, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE) movementMethod = LinkMovementMethod.getInstance() text = style }
Its use
myTextView.colorText("User agreement","#118EEA"){ //Own click events }
6, Summary
The encapsulation is generally good. It simplifies the code and applies Kotlin's knowledge. Welcome to leave a message