Android rich text summary

1. Introduction to application scenarios

In Android application development, there are many UIs that will draw some particularly cool interfaces. There will be special words in a line of text that will be other colors and bold. To emphasize, we can use a few stupid ways to do this. TextView to link, but device adaptation is a problem, because what should I do if the colored text happens to be at the line break. There may even be some icons interspersed in a piece of text, so what to do? So today our protagonist rich text editor solves this problem very well.

2. What rich text SpannableString can do

Add various styles and events to specific places in the text. Styles include color, size, background, strikethrough, superscript and subscript, bold italics, and pictures. Events include click events, hyperlinks, etc. The core code is

val sb = SpannableString(content) //content表示文本内容
sb.setSpan(
	ForegroundColorSpan(specailColor), //span类型
 	startIndex, //span的起始index
 	endIndx, //span的结束index(一般为startIndex + replaceTxt.length)
 	Spannable.SPAN_EXCLUSIVE_EXCLUSIVE //span类型,设置startIndex和endIndex的开闭区间
)
textview.text = sb

Special: The last parameter flag of the setSpan method has the following four values:
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE: neither before nor after, that is, inserting new characters before and after the specified range will not apply the new style (start, end)
Spannable. SPAN_EXCLUSIVE_INCLUSIVE: Exclude the former and include the latter. That is, the new style will be applied only when new characters are inserted after the range character (start, end]
Spannable.SPAN_INCLUSIVE_EXCLUSIVE: Included before and not included after. [start, end)
Spannable.SPAN_INCLUSIVE_INCLUSIVE: Included both before and after. [start,end]

3. Simple span application example

3.1. Text color

val content = "这是一段文字,需要特殊颜色的内容"
val replaceTxt = "特殊颜色"
val sb = SpannableString(content) //content表示文本内容
val startIndex = content.indexOf(replaceTxt)
val endIndex = startIndex + replaceTxt.length
val specailColor = Color.parseColor("#0644a3")
sb.setSpan(
   ForegroundColorSpan(specailColor), //span类型 specailColor颜色
	startIndex, //span的起始index
	endIndx, //span的结束index(一般为startIndex + replaceTxt.length)
	Spannable.SPAN_EXCLUSIVE_EXCLUSIVE //span类型,设置startIndex和endIndex的开闭区间
)
textview.text = sb

3.2. Click on special text

val content = "这是一段文字,需要点击效果的内容"
val replaceTxt = "点击效果"
val sb = SpannableString(content) //content表示文本内容
val startIndex = content.indexOf(replaceTxt)
val endIndex = startIndex + replaceTxt.length
val sb = SpannableString(content) //content表示文本内容
val clickSpan: ClickableSpan = object : ClickableSpan() {
    
    
           override fun onClick(widget: View) {
    
    
          			Toast.makeText(context, "点击$replaceTxt", Toast.LENGTH_SHORT).show()
           }
           
           override fun updateDrawState(ds: TextPaint) {
    
    
               ds.run {
    
     //这里可以动态设置点击区域字符的字体样式,比如颜色、字体、大小、下划线、删除线等
                   typeface = FontManager.getNumberFont()
                   color = ContextCompat.getColor(context, R.color.c_fe0000)
               }
           }
       }
sb.setSpan(
   clickSpan, //span类型
	startIndex, //span的起始index
	endIndx, //span的结束index(一般为startIndex + replaceTxt.length)
	Spannable.SPAN_EXCLUSIVE_EXCLUSIVE //span类型,设置startIndex和endIndex的开闭区间
)
textview.movementMethod = LinkMovementMethod.getInstance()  //点击需要设置,不然没有点击事件
// textview点击时会有一个高亮色,如果不需要可以设置highlightColor为透明色
textview.text = sb

3.3. Text font size

val sb = SpannableString(content) //content表示文本内容
sb.setSpan(
   AbsoluteSizeSpan(26,true), //第二个参数表示单位是否是dp
	startIndex, //span的起始index
	endIndx, //span的结束index(一般为startIndex + replaceTxt.length)
	Spannable.SPAN_EXCLUSIVE_EXCLUSIVE //span类型,设置startIndex和endIndex的开闭区间
)
textview.text = sb

3.4. Insert icons into text

val sb = SpannableString(content) //content表示文本内容
val d = getResources().getDrawable(R.mipmap.ic_launcher)
d.setBounds(0, 0, d.getIntrinsicWidth(), d.getIntrinsicHeight())
val span = ImageSpan(d, ImageSpan.ALIGN_BASELINE) //图标基于文本基线对齐 对齐方式默认底部对齐
sb.setSpan(
   span, //span类型
	startIndex, //span的起始index
	endIndx, //span的结束index(一般为startIndex + replaceTxt.length)
	Spannable.SPAN_EXCLUSIVE_EXCLUSIVE //span类型,设置startIndex和endIndex的开闭区间
)
textview.text = sb

4. SpannableStringBuilder and SpannableString

SpannableString can only set one span. If there are multiple special effects at different positions in a piece of content, it cannot be implemented. Of course, for multiple special effects at the same position, we can override Span's updateDrawState(ds: TextPaint) method.
SpannableStringBuilder can set multiple spans, and each span can be set in a different position or at the same position.
How to use it

val spb = SpannableStringBuilder(content)
spb.setSpan(span1, start, end, flag)
spb.setSpan(span2, start, end, flag)
textview.text = spb

Special: The content in SpannableStringBuilder can be added through append(text: String). After adding new content, you need to pay attention to the subscript change of the content.

Guess you like

Origin blog.csdn.net/qq_39734865/article/details/95461325