美文网首页
textview - SpannableString 小工具

textview - SpannableString 小工具

作者: 前行的乌龟 | 来源:发表于2018-09-11 20:56 被阅读101次

    昨天总结了下 SpannableString 的用法,在学习之后发现 SpannableString 还是能干很多事的,我的印象里记得 SpannableString 也就是能改个颜色,改个大小。所以这次看完也不知道记忆能保鲜多久,怕忘,想了想还是写个小工具好些,一是加强印象,这写和不写完全是2个概念,二是以后也方便用

    项目地址:BW_Libs

    Snip20180910_4.png

    代码设计


    1. 首先像 SpannableString 这种功能单一,类很少的,只能成为 utils 工具,而不能叫 lib 库的,所以起名就叫 SpanUtils 好了
            SpanUtils
                    .with(tx01)
                    .foregroundColor(Color.BLUE, tx01.text.indexOf("-") + 1, tx01.text.length)
                    .show()
    
    1. 工具类一般都需要有统一的入口的,所以我们使用 kotlin + 静态单例的方式来提供工具使用规范。为了赶上链式调用的春风,可以不停的 . 下去,所以我们就不能直接返回 SpannableString 对象了,而是我们写的 SpannableString 功能包装类。开始的资源绑定方法,我们提供2个重载,可以接受 String 和 TextView
        companion object {
    
            fun with(text: String): SpanUtils {
                return SpanUtils(text)
            }
    
            fun with(textView: TextView): SpanUtils {
                return SpanUtils(textView, textView.text.toString())
            }
        }
    
    1. 最后我们也提供显示的重载,除了可以使用已经绑定的 TextView 外,也可以指定 TextView,
    
        fun show() {
            textView?.setText(spannable)
        }
    
        fun show(textView: TextView?) {
            textView?.setText(spannable)
        }
    
    
    1. 然后我们再提供获取最终的 String 和 SpannableString 的方法
    
        fun getString(): String {
            return spannable.toString()
        }
    
        fun getSpannableString(): SpannableString {
            return spannable
        }
    
    1. 这样的话这个小工具基本就齐活了,在使用上也能做到比较灵活了。我一直觉得小的进步积累多了之后就是巨大的改变,这样的技术进步才是最稳的,不知不觉的我们就可以写出不错的能看的工具,库,组件出来了。

    最后代码


    class SpanUtils(text: String) {
    
        // SpannableString 文字样式对象
        lateinit var spannable: SpannableString
        // 关联的 view
        var textView: TextView? = null
    
        companion object {
    
            /**
             * 全局静态入口
             */
            fun with(text: String): SpanUtils {
                return SpanUtils(text)
            }
    
            /**
             * 全局静态入口
             */
            fun with(textView: TextView): SpanUtils {
                return SpanUtils(textView, textView.text.toString())
            }
        }
    
        /**
         * 主构造函数里,初始化 SpannableString 对象
         */
        init {
            this.spannable = SpannableString(text)
        }
    
        constructor(textView: TextView, text: String) : this(text) {
            this.textView = textView
        }
    
        /**
         * 返回最终结果
         */
        fun getString(): String {
            return spannable.toString()
        }
    
        /**
         * 返回最终结果
         */
        fun getSpannableString(): SpannableString {
            return spannable
        }
    
        /**
         * 显示
         */
        fun show() {
            textView?.setText(spannable)
        }
    
        /**
         * 显示
         */
        fun show(textView: TextView?) {
            textView?.setText(spannable)
        }
    
        /**
         * 添加前景色
         */
        fun foregroundColor(color: Int, startIndex: Int, endIndex: Int): SpanUtils {
            var forColorSpan = ForegroundColorSpan(color)
            spannable.setSpan(forColorSpan, startIndex, endIndex, SpannableString.SPAN_INCLUSIVE_EXCLUSIVE)
            return this@SpanUtils
        }
    
        /**
         * 添加前景色
         */
        fun backgroundColor(color: Int, startIndex: Int, endIndex: Int): SpanUtils {
            var backColorSpan = BackgroundColorSpan(color)
            spannable.setSpan(backColorSpan, startIndex, endIndex, SpannableString.SPAN_INCLUSIVE_EXCLUSIVE)
            return this@SpanUtils
        }
    
        /**
         * 相对文字大小
         * size: 应使用诸如 1.2F 这样的参数格式
         */
        fun relativeTextSize(size: Float, startIndex: Int, endIndex: Int): SpanUtils {
            var relativeSizeSpan = RelativeSizeSpan(size)
            spannable.setSpan(relativeSizeSpan, startIndex, endIndex, SpannableString.SPAN_INCLUSIVE_EXCLUSIVE)
            return this@SpanUtils
        }
    
        /**
         * 绝对文字大小
         * size: 应使用 sp 转换成的 int 值
         */
        fun absoluteTextSize(size: Int, startIndex: Int, endIndex: Int): SpanUtils {
            var absoluteSizeSpan = AbsoluteSizeSpan(size)
            spannable.setSpan(absoluteSizeSpan, startIndex, endIndex, SpannableString.SPAN_INCLUSIVE_EXCLUSIVE)
            return this@SpanUtils
        }
    
        /**
         * 中划线
         */
        fun middleLine(startIndex: Int, endIndex: Int): SpanUtils {
            var strikethroughSpan = StrikethroughSpan()
            spannable.setSpan(strikethroughSpan, startIndex, endIndex, SpannableString.SPAN_INCLUSIVE_EXCLUSIVE)
            return this@SpanUtils
        }
    
        /**
         * 下划线
         */
        fun underLine(startIndex: Int, endIndex: Int): SpanUtils {
            var underLineSpan = UnderlineSpan()
            spannable.setSpan(underLineSpan, startIndex, endIndex, SpannableString.SPAN_INCLUSIVE_EXCLUSIVE)
            return this@SpanUtils
        }
    
        /**
         * 上标
         * 请允许我使用自创单词,因为原生单词实在不好记忆,也容易和下标混淆
         */
        fun topFlag(startIndex: Int, endIndex: Int): SpanUtils {
            var superscriptSpan = SuperscriptSpan()
            spannable.setSpan(superscriptSpan, startIndex, endIndex, SpannableString.SPAN_INCLUSIVE_EXCLUSIVE)
            return this@SpanUtils
        }
    
        /**
         * 下标
         * 请允许我使用自创单词,因为原生单词实在不好记忆,也容易和上标混淆
         */
        fun bottomFlag(startIndex: Int, endIndex: Int): SpanUtils {
            var subscriptSpan = SubscriptSpan()
            spannable.setSpan(subscriptSpan, startIndex, endIndex, SpannableString.SPAN_INCLUSIVE_EXCLUSIVE)
            return this@SpanUtils
        }
    
        /**
         * 粗体
         */
        fun bold(startIndex: Int, endIndex: Int): SpanUtils {
            var boldSpan = StyleSpan(Typeface.BOLD)
            spannable.setSpan(boldSpan, startIndex, endIndex, SpannableString.SPAN_INCLUSIVE_EXCLUSIVE)
            return this@SpanUtils
        }
    
        /**
         * 斜体
         */
        fun italic(startIndex: Int, endIndex: Int): SpanUtils {
            var italicSpan = StyleSpan(Typeface.ITALIC)
            spannable.setSpan(italicSpan, startIndex, endIndex, SpannableString.SPAN_INCLUSIVE_EXCLUSIVE)
            return this@SpanUtils
        }
    
        /**
         * 斜粗体
         */
        fun italicAndBlod(startIndex: Int, endIndex: Int): SpanUtils {
            var italicAndBlodSpan = StyleSpan(Typeface.BOLD_ITALIC)
            spannable.setSpan(italicAndBlodSpan, startIndex, endIndex, SpannableString.SPAN_INCLUSIVE_EXCLUSIVE)
            return this@SpanUtils
        }
    
        /**
         * 斜粗体
         * drawable: 图片必须显示的指名大小,才能有效显示,请参考 - drawable.setBounds(0, 0, 80, 80)
         */
        fun image(drawable: Drawable, startIndex: Int, endIndex: Int): SpanUtils {
            var imageSpan = ImageSpan(drawable)
            spannable.setSpan(imageSpan, startIndex, endIndex, SpannableString.SPAN_INCLUSIVE_EXCLUSIVE)
            return this@SpanUtils
        }
    
        /**
         * 可点击区域
         * textView: 必须设置 setMovementMethod() 方法才能实现点击
         */
        fun clickable(textView: TextView, ClickableSpan: ClickableSpan, startIndex: Int, endIndex: Int): SpanUtils {
            spannable.setSpan(ClickableSpan, startIndex, endIndex, SpannableString.SPAN_INCLUSIVE_EXCLUSIVE)
            textView.setMovementMethod(LinkMovementMethod.getInstance())
            return this@SpanUtils
        }
    
        /**
         * 超链接
         * adress: 必须加 http:// 协议才能正常跳转到系统浏览器
         */
        fun url(textView: TextView, adress: String, startIndex: Int, endIndex: Int): SpanUtils {
            var urlSpan = URLSpan(adress)
            spannable.setSpan(urlSpan, startIndex, endIndex, SpannableString.SPAN_INCLUSIVE_EXCLUSIVE)
            textView.setMovementMethod(LinkMovementMethod.getInstance())
            return this@SpanUtils
        }
    
    }
    

    参考资料


    相关文章

      网友评论

          本文标题:textview - SpannableString 小工具

          本文链接:https://www.haomeiwen.com/subject/zrkpgftx.html