• 安卓TextView调整下划线颜色、与文本底部的距离


    需要自定义view来实现,因为安卓的TextView没有提供设置颜色与间距的方法

    实现效果

    • 下划线颜色与文字不一样
    • 下划线距离文字底部的边界可调整
    • 但只能标记同一行的文字,也就是说下划线的start与end在同一行。还没多行的需求,有时间再说
      在这里插入图片描述
    package com.XXX
    
    import android.annotation.SuppressLint
    import android.content.Context
    import android.graphics.Canvas
    import android.graphics.Paint
    import android.graphics.Rect
    import android.util.AttributeSet
    import android.util.Log
    import androidx.annotation.ColorRes
    import androidx.appcompat.widget.AppCompatTextView
    import androidx.core.content.ContextCompat
    import com.XXX.R
    
    /**
     * 设置下划线,支持设置下划线颜色、文本底部矩形边界与下划线的间距;下划线仅支持展示在一行
     */
    class OnSameLineUnderLineTextView @JvmOverloads constructor(
        context: Context,
        attrs: AttributeSet? = null,
        defStyleAttr: Int = 0
    ) : AppCompatTextView(context, attrs, defStyleAttr) {
    
        private var start: Int = 0
        private var end: Int = 0
        private var widthDp: Float = 1f
        private var colorRes: Int = R.color.black
        private var offsetOfY: Float = 0f
    
        /**
         * 给文字设置下划线
         * @param   start 下划线初始字符的索引
         *          end   下划线结束字符的索引
         *          widthDp 下划线的高度
         *          colorRes 颜色
         *          offsetOfY 底部边界
         */
        fun drawUnderLine(start: Int,
                          end: Int,
                          widthDp: Float = this.widthDp,
                          @ColorRes colorRes: Int = this.colorRes,
                          offsetOfY: Float = 0f) {
            this.start = start
            this.end = end
            this.widthDp = widthDp
            this.colorRes = colorRes
            this.offsetOfY = offsetOfY
            invalidate()
          
        }
    
    
        @SuppressLint("DrawAllocation")
        override fun onDraw(canvas: Canvas) {
    
            if (this.start >= this.end) return
    
            val paint = Paint()
            paint.color = ContextCompat.getColor(context, this.colorRes)
            paint.strokeWidth = widthDp
    
            //只有同一行生效
            val lineStart = layout.getLineForOffset(start)
            val lineEnd = layout.getLineForOffset(end)
    
            if (lineStart == lineEnd) {
                val bound = Rect()
                layout.getLineBounds(lineStart, bound)
    
                val startXBottom = layout.getPrimaryHorizontal(start)
                val startYBottom = bound.bottom.toFloat()
    
                val endXBottom = layout.getSecondaryHorizontal(end)
                val endYBottom = bound.bottom.toFloat()
    
                canvas.drawLine(startXBottom, startYBottom + offsetOfY, endXBottom, endYBottom + offsetOfY, paint)
            } else {
            	//待实现多行逻辑
            }
    
            super.onDraw(canvas)
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83

    调用

    //你的字符串,注意需要下划线的那段文字需要在同一行!!我是直接在差不多的位置加的"\n"
    val baseString = itemView.context.getString(bean.content)
    //需要下划线的那段字
    val lineString = itemView.context.getString(bean.contentSub)
    //找到需下划线文字的开头索引
    val indexOf = baseString.indexOf(lineString)
    if (indexOf >= 0) {
    	//给textview加6dp,指定颜色的下划线,
        mProductTitle.drawUnderLine(indexOf, indexOf + lineString.length,
            SmartUtil.dp2px(6f).toFloat(), bean.contentSubUnderLineColorRes,
            SmartUtil.dp2px(-9f).toFloat()
        )
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    那个-9是怎么来的?

    最后说一下上面调用的代码中 第五个参数传“-9”是怎么来的

    mProductTitle.drawUnderLine(indexOf, indexOf + lineString.length,
            SmartUtil.dp2px(6f).toFloat(), bean.contentSubUnderLineColorRes,
            SmartUtil.dp2px(-9f).toFloat()
        )
    
    • 1
    • 2
    • 3
    • 4

    因为TextView每行文字底部的边界不是文字的边界,在自定义view时layout.getLineBounds找到的底部边界时每行文字所在矩形的底边,“-9”就相当于 相对这个底边的offset,需要你自己调

    如果能帮助到您,请点个👍吧 谢谢啦

  • 相关阅读:
    跟着官方文档学习axios
    js:React中使用classnames实现按照条件将类名连接起来
    如何安装和配置solr
    Flex and Bison 阅读与学习笔记
    SpEl简单使用
    MySQL入门(SQL语句、约束)
    USACO18OPEN Talent Show G
    Eureka 入门教程
    gitlab-runner 的安装使用(含 .gitlab-ci.yml 的简单使用)
    KASan介绍
  • 原文地址:https://blog.csdn.net/qq_44477844/article/details/134299722