安卓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)
    }
}

调用

//你的字符串,注意需要下划线的那段文字需要在同一行!!我是直接在差不多的位置加的"\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是怎么来的?

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

mProductTitle.drawUnderLine(indexOf, indexOf + lineString.length,
        SmartUtil.dp2px(6f).toFloat(), bean.contentSubUnderLineColorRes,
        SmartUtil.dp2px(-9f).toFloat()
    )

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

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/122318.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

css style、css color 转 UIColor

你能看过来,就说明这个问题很好玩!IT开发是一个兴趣,更是一个挑战!兴趣使你工作有热情。挑战使让你工作充满刺激拉满的状态!我们日复一日年复一年的去撸代码,那些普普通通的功能代码,已经厌倦了…

2023_11_6 每日半小时 SQL 刷题

文章目录 1. 查询所有列题目描述SQL 语句编写 2. 查询多列题目描述SQL 语句编写 3. 查询结果去重题目描述SQL 语句编写 4. 查询结果限制返回行数题目描述SQL 语句编写 5. 将查询后的列重新命名题目描述SQL 语句编写 语法小总结 1. 查询所有列 题目链接:SQL1 查询所…

SpringCloud——服务注册——Eureka

1.Eureka概述 2.Eureka架构: Eureka中80服务要实现对8001和8002服务访问的负载均衡,需要在80服务的RestTemplate上面加LoadBalanced注解,默认采用的是轮询的策略。 3.Eureka自我保护 当一个EurekaClient注册进EurekaServer,Eurek…

每日一题 2258. 逃离火灾(手撕困难!!!)

火会扩散,但是我们可以看作火不会扩散到已经着火的格子,这样我们就可以记录每一个为草地的格子的着火时间在代码中,因为数字 2 已经表示墙了,所以我们把当时间为 0 时着火的格子在 gird 中的值设为 3,时间为 1 时着火的…

2023年开发语言和数据库排行

2023年开发语言和数据库排行 一、开发语言相关1. Python1.1 Python优点1.2 Python缺点1.3 Python应用领域 2. C 语言2.1 C 语言优点2.2 C 语言缺点2.3 C语言应用领域 3. Java3.1 Java 优点3.2 Java缺点3.3 Java应用场景 4. C4.1 C 优点4.2 C 缺点4.3 C 应用场景 5. C#5.1 C# 优…

(附源码)基于Springboot智慧园区管理系统-计算机毕设 88160

Springboot智慧园区管理系统的开发 摘要 随着互联网趋势的到来,互联网概念越来越盛行,园区管理最好方式就是建立自己的互联网系统。在现实运用中,应用软件的工作规则和开发步骤,采用Springboot框架建设智慧园区管理系统。 本设计主…

C语言 做一个学生信息管理系统

#include<stdio.h> #include<string.h> #include<stdlib.h> typedef struct person {char name[30];char sex[10];int num;struct person *next; }stu; stu *head NULL; void printf_link(stu *head) {stu *pd head;while(pd ! NULL){printf("姓名&a…

深度学习读取txt训练数据绘制参数曲线图的方法

有一些深度学习模型是并不像yolo系列那样最终输出相应的参数图&#xff0c;有很多训练形成了一个训练log文件&#xff0c;于是需要读取log文件中的内容并绘制成曲线图。 如下实例&#xff0c;有一个log文件的部分截图&#xff0c;需要将其读取出来并绘制曲线图 废话不多说&…

物联网AI MicroPython学习之语法 ucollections集合和容器类型

学物联网&#xff0c;来万物简单IoT物联网&#xff01;&#xff01; ucollections 介绍 ucollections 模块用于创建一个新的容器类型&#xff0c;用于保存各种对象。 接口说明 namedtuple - 创建一个新namedtuple容器类型 函数原型&#xff1a; 创建一个具有特定名称和一组…

QT QStackedWidget

QStackedWidget是一个特殊的布局容器&#xff0c;它可以管理多个页面&#xff0c;并且只能显示其中一个页面。这些页面是QWidget或其派生类的实例&#xff0c;并通过调用addWidget()函数添加到堆栈中。 例如&#xff1a; #include <QWidgets> #include <QStackedWid…

一文掌握 Apache SkyWalking

Apache SkyWalking SkyWalking是一个开源可观测平台&#xff0c;用于收集、分析、聚合和可视化来自服务和云原生基础设施的数据。SkyWalking 提供了一种简单的方法来保持分布式系统的清晰视图&#xff0c;甚至跨云。它是一种现代APM&#xff0c;专为云原生、基于容器的分布式系…

绿联DX4600 AList部署及挂载阿里云盘

写在前面 ​ 因为云盘总是封禁已经转存的文件&#xff08;珍惜影片&#xff09;&#xff0c;实在受不了了&#xff0c;就像购买个NAS构建私人云存储&#xff0c;正好趁着双11购入了绿联的DX4600&#xff0c;本来想购入群晖或者威联通等专业NAS&#xff0c;因为不想折腾&#x…

SQL Server SSIS ETL job执行相关操作

创建SSIS项目 Excel导入SQL Server 构建Excel源 配置Excel源信息 配置SQL Server目标 双击“ADO NET目标” job执行 新建job 右键“SQL Server代理”的“作业”&#xff0c;点击“新建作业”&#xff0c;弹出“新建作业”的选项页 首先是“常规”选项页&#xff0c;…

RRC configured BWP

TS 38.822有UE BWP 相关能力 IE的详细介绍,如下图。 举例说明,对于UE上报bwp-SameNumerology=upto2时,根据上图中的描述,UE支持能力情况如下:每个carrier最多支持2 个UE specific RRC configured DL/UL BWPs;可以通过DCI和BWP-InactivityTimer主动切换BWP;每个carrier的…

聚焦谋发展,筑梦新征程——云起无垠乔迁新址

2021年7月&#xff0c;网络安全新锐企业北京云起无垠科技有限公司&#xff08;以下简称&#xff1a;云起无垠&#xff09;注册成立。云起无垠致力于研究漏洞挖掘尖端技术和打造卓越漏挖工具&#xff0c;并在业界迅速崭露头角&#xff0c;受到了广泛瞩目。 发展至今&#xff0c…

CSS中calc(80vw - 100px)为什么不加空格会不生效?

问题起因 今天再使用calc时发现无法生效&#xff0c;我的写法是&#xff1a; width: calc(100%-100px);页面无效果&#xff0c;加空格后就发现有效果了&#xff1a; width: calc(100% - 100px);有亿点疑惑&#xff0c;这是为什么&#xff1f; calc是什么&#xff1f; css3的…

Java用Jsoup库实现的多线程爬虫代码

因为没有提供具体的Python多线程跑数据的内容&#xff0c;所以我们将假设你想要爬取的网站是一个简单的URL。以下是一个基本的Java爬虫程序&#xff0c;使用了Jsoup库来解析HTML和爬虫ip信息。 import org.jsoup.Jsoup; import org.jsoup.nodes.Document; import org.jsoup.nod…

[python 刷题] 437 Path Sum III

[python 刷题] 437 Path Sum III 之前有写过 Path Sum I & II, leetcode 112 & 113&#xff0c;虽然使用 JS 写的&#xff0c;不过 python 的实现也更新了一下 题目如下&#xff1a; Given the root of a binary tree and an integer targetSum, return the number o…

1-前端基本知识-CSS

1-前端基本知识-CSS 文章目录 1-前端基本知识-CSS总体概述什么是CSS&#xff1f;CSS引入方式行内式内嵌式连接式/外部样式表 CSS选择器元素选择器id选择器class选择器&#xff08;使用较广&#xff09; CSS浮动CSS定位静态定位&#xff1a;static绝对定位&#xff1a;absolute相…

【Linux】:文件系统

文件系统 一.认识硬件-磁盘1.磁盘的物理构成2.磁盘的存储构成3.逻辑结构 二.文件系统1.基本概念2.硬链接2.软链接 文件内容属性&#xff0c;前面我们所说的文件操作都是针对以打开的文件&#xff0c;那么未打开的文件呢&#xff1f;当然是在磁盘上储存着&#xff0c;接下来谈谈…