经常使用 SpannableString ,所以写了个扩展函数
类名: SpannableStringExt.kt
package xxx
import android.graphics.Typeface
import android.graphics.drawable.Drawable
import android.text.Spannable
import android.text.SpannableString
import android.text.method.LinkMovementMethod
import android.text.style.AbsoluteSizeSpan
import android.text.style.BackgroundColorSpan
import android.text.style.ClickableSpan
import android.text.style.ForegroundColorSpan
import android.text.style.ImageSpan
import android.text.style.StrikethroughSpan
import android.text.style.StyleSpan
import android.text.style.SubscriptSpan
import android.text.style.SuperscriptSpan
import android.text.style.URLSpan
import android.text.style.UnderlineSpan
import android.view.View
import android.widget.TextView
import com.geaosu.libsExtensions.span.ClickableSpanWithOutUnderLine
fun SpannableString.addColor(target: String, color: Int, flags: Int = Spannable.SPAN_EXCLUSIVE_EXCLUSIVE): SpannableString {
if (containsSubstring(target)) {
val startIndex: Int = this.indexOf(target)
val endIndex = startIndex + target.length
this.setSpan(ForegroundColorSpan(color), startIndex, endIndex, flags)
}
return this
}
fun SpannableString.addBgColor(target: String, color: Int, flags: Int = Spannable.SPAN_EXCLUSIVE_EXCLUSIVE): SpannableString {
if (containsSubstring(target)) {
val startIndex: Int = this.indexOf(target)
val endIndex = startIndex + target.length
this.setSpan(BackgroundColorSpan(color), startIndex, endIndex, flags)
}
return this
}
fun SpannableString.addBold(target: String, flags: Int = Spannable.SPAN_EXCLUSIVE_EXCLUSIVE): SpannableString {
if (containsSubstring(target)) {
val startIndex: Int = this.indexOf(target)
val endIndex = startIndex + target.length
this.setSpan(StyleSpan(Typeface.BOLD), startIndex, endIndex, flags)
}
return this
}
fun SpannableString.addItalics(target: String, flags: Int = Spannable.SPAN_EXCLUSIVE_EXCLUSIVE): SpannableString {
if (containsSubstring(target)) {
val startIndex: Int = this.indexOf(target)
val endIndex = startIndex + target.length
this.setSpan(StyleSpan(Typeface.ITALIC), startIndex, endIndex, flags)
}
return this
}
fun SpannableString.addUnderline(target: String, flags: Int = Spannable.SPAN_EXCLUSIVE_EXCLUSIVE): SpannableString {
if (containsSubstring(target)) {
val startIndex: Int = this.indexOf(target)
val endIndex = startIndex + target.length
this.setSpan(UnderlineSpan(), startIndex, endIndex, flags)
}
return this
}
fun SpannableString.addDeleteLine(target: String, flags: Int = Spannable.SPAN_EXCLUSIVE_EXCLUSIVE): SpannableString {
if (containsSubstring(target)) {
val startIndex: Int = this.indexOf(target)
val endIndex = startIndex + target.length
this.setSpan(StrikethroughSpan(), startIndex, endIndex, flags)
}
return this
}
fun SpannableString.addSize(target: String, size: Int, flags: Int = Spannable.SPAN_EXCLUSIVE_EXCLUSIVE): SpannableString {
if (containsSubstring(target)) {
val startIndex: Int = this.indexOf(target)
val endIndex = startIndex + target.length
this.setSpan(AbsoluteSizeSpan(size), startIndex, endIndex, flags)
}
return this
}
fun SpannableString.addImage(drawable: Drawable, drawableWith: Int, drawableHeight: Int, startIndex: Int, flags: Int = ImageSpan.ALIGN_CENTER): SpannableString {
drawable.setBounds(0, 0, drawableWith, drawableHeight)
this.setSpan(ImageSpan(drawable), startIndex, startIndex + 1, flags)
return this
}
fun SpannableString.addImageOnStart(drawable: Drawable, drawableWith: Int, drawableHeight: Int, flags: Int = ImageSpan.ALIGN_CENTER): SpannableString {
drawable.setBounds(0, 0, drawableWith, drawableHeight)
this.setSpan(ImageSpan(drawable), 0, 1, flags)
return this
}
fun SpannableString.addSup(target: String, flags: Int = Spannable.SPAN_EXCLUSIVE_EXCLUSIVE): SpannableString {
if (containsSubstring(target)) {
val startIndex: Int = this.indexOf(target)
val endIndex = startIndex + target.length
this.setSpan(SuperscriptSpan(), startIndex, endIndex, flags)
}
return this
}
fun SpannableString.addSizeSub(target: String, flags: Int = Spannable.SPAN_EXCLUSIVE_EXCLUSIVE): SpannableString {
if (containsSubstring(target)) {
val startIndex: Int = this.indexOf(target)
val endIndex = startIndex + target.length
this.setSpan(SubscriptSpan(), startIndex, endIndex, flags)
}
return this
}
fun SpannableString.addOnClickListener(target: String, listener: View.OnClickListener, flags: Int = Spannable.SPAN_EXCLUSIVE_EXCLUSIVE): SpannableString {
if (containsSubstring(target)) {
val startIndex: Int = this.indexOf(target)
val endIndex = startIndex + target.length
this.setSpan(object : ClickableSpan() {
override fun onClick(widget: View) {
listener.onClick(widget)
}
}, startIndex, endIndex, flags)
}
return this
}
fun SpannableString.addOnClickListenerWithOutUnderline(target: String, listener: View.OnClickListener, flags: Int = Spannable.SPAN_EXCLUSIVE_EXCLUSIVE): SpannableString {
if (containsSubstring(target)) {
val startIndex: Int = this.indexOf(target)
val endIndex = startIndex + target.length
this.setSpan(object : ClickableSpanWithOutUnderLine() {
override fun onClick(widget: View) {
listener.onClick(widget)
}
}, startIndex, endIndex, flags)
}
return this
}
fun SpannableString.addPhoneClick(phoneNo: String, flags: Int = Spannable.SPAN_EXCLUSIVE_EXCLUSIVE): SpannableString {
if (containsSubstring(phoneNo)) {
val startIndex: Int = this.indexOf(phoneNo)
val endIndex = startIndex + phoneNo.length
this.setSpan(URLSpan("tel:$phoneNo"), startIndex, endIndex, flags)
}
return this
}
fun SpannableString.addPhoneClick(title: String, phoneNo: String, flags: Int = Spannable.SPAN_EXCLUSIVE_EXCLUSIVE): SpannableString {
if (containsSubstring(title)) {
val startIndex: Int = this.indexOf(title)
val endIndex = startIndex + title.length
this.setSpan(URLSpan("tel:$phoneNo"), startIndex, endIndex, flags)
}
return this
}
fun SpannableString.addUrlClick(url: String, flags: Int = Spannable.SPAN_EXCLUSIVE_EXCLUSIVE): SpannableString {
if (containsSubstring(url)) {
val startIndex: Int = this.indexOf(url)
val endIndex = startIndex + url.length
this.setSpan(URLSpan(url), startIndex, endIndex, flags)
}
return this
}
fun SpannableString.addUrlClick(title: String, url: String, flags: Int = Spannable.SPAN_EXCLUSIVE_EXCLUSIVE): SpannableString {
if (containsSubstring(title)) {
val startIndex: Int = this.indexOf(title)
val endIndex = startIndex + title.length
this.setSpan(URLSpan(url), startIndex, endIndex, flags)
}
return this
}
fun SpannableString.containsSubstring(target: String): Boolean {
return this.toString().contains(target)
}
fun SpannableString.setSpannableStringClickEnable(textView: TextView): SpannableString {
textView.movementMethod = LinkMovementMethod.getInstance()
return this
}
fun SpannableString.into(textView: TextView) {
textView.movementMethod = LinkMovementMethod.getInstance()
textView.text = this
}
默认的点击事件文字带下划线,这里提供一个不带下划线的 ClickableSpanWithOutUnderLine
package com.geaosu.libsExtensions.span;
import android.text.TextPaint;
import android.text.style.ClickableSpan;
public abstract class ClickableSpanWithOutUnderLine extends ClickableSpan {
@Override
public void updateDrawState(TextPaint ds) {
ds.setUnderlineText(false);
}
}