赞
踩
需要自定义view来实现,因为安卓的TextView没有提供设置颜色与间距的方法
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) } }
//你的字符串,注意需要下划线的那段文字需要在同一行!!我是直接在差不多的位置加的"\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()
)
}
最后说一下上面调用的代码中 第五个参数传“-9”是怎么来的
mProductTitle.drawUnderLine(indexOf, indexOf + lineString.length,
SmartUtil.dp2px(6f).toFloat(), bean.contentSubUnderLineColorRes,
SmartUtil.dp2px(-9f).toFloat()
)
因为TextView每行文字底部的边界不是文字的边界,在自定义view时layout.getLineBounds
找到的底部边界时每行文字所在矩形的底边,“-9”就相当于 相对这个底边的offset,需要你自己调
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。