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

news2024/11/24 9:13:51

需要自定义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,需要你自己调

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

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

RuntimeError_ Found dtype Long but expected Float

在跑模型的时候,出现了报错: RuntimeError: Found dtype Long but expected Float报错是发生在BCE loss 的部分,因为crossentropyloss要求batch_label必须为torch.float类型 所以需要修改一下标签,转为float格式就好了&#xff1…

setpci设定PCIe寄存器

PCIe寄存器信息读取、分析、配置 1.获取bdf (bus:device.function)地址2.根据bdf地址抓取pci信息3.结合PCIe Spec对读到的信息进行分析使用setpci修改 1.获取bdf (bus:device.function)地址 在Linux系统下使用命令: l…

web3 React dapp项目通过事件从区块链中拿到 已取消 已完成 和所有的订单数据 并存入redux中

好 上文web3通过antd 在React dapp中构建订单组件基本结构我们算是把一个基本的订单组件展示做出来了 然后 我们继续 起一下环境先 ganache 终端运行 ganache -dMetaMask 登录一下 然后 打开项目 发布一下合约 truffle migrate --reset然后 运行一下 测试脚本 转入交易所 E…

云尘靶场 --JIS-CTF-VulnUpload

重新下vpn连接的文件 还是fscan扫 访问一下13 到了/login.php 随便弱口令试试 好吧没成功,那目录扫描一下 那就先看一下robots.txt了 flag有点快的 抱着试一试的态度看一下admin_area 没想到源代码里面居然有 这么这么多 本来还以为密码要去爆破的&#xff0…

webrtc推拉流 srs报错:DTLS_HANG DTLS: > Hang, done=0, version=-1, arq=0

执行了./objs/srs -c conf/rtc.conf 打开了srs的推拉流网页: 推流 拉流 srs报错如下: [2023-11-08 21:55:23.489][Warn][44992][8xvf4d62][104][DTLS_HANG] DTLS: Hang, done0, version-1, arq0 观看srs日志,在sdp offer,answer…

Qlik Sense : Fetching data with Qlik Web Connectors

目录 Connecting to data sources Opening a connector Connecting to a data source Authenticating the connector Defining table parameters Using standard mode or legacy mode Standard mode Connector overview Using multi-line input parameters to fetch da…

提前尝鲜!铁威马TOS 6内测招募中,赢取“遥遥领先”!

铁威马NAS的出现为我们解决了绝大部分的数据存储难题,而作为国民专业级NAS的铁威马,也从未停止前进的脚步,不断的升级和改造,致力于为用户打造一个更友好更安全的存储环境。 铁威马全新操作系统TOS 6来了!40多项新功能…

制药企业如何提高员工的GMP合规意识

在上期的文章中,我们介绍了>>制药企业计算机化系统验证(CSV)的重要性,本期我们深入探讨制药企业如何培养员工形成GMP良好的合规意识。 良好的药品质量是保障患者安全和有效治疗的基石。为了确保药品的质量、安全性和一致性,制药企业必…

美国财政部制裁俄罗斯洗钱人士打击网络犯罪

导语 美国财政部近日对一名37岁的俄罗斯女子实施了制裁,原因是她参与了为俄罗斯精英和网络犯罪团伙洗钱的行为。这一行动旨在打击网络犯罪活动,保护国际金融市场的安全。本文将详细介绍制裁对象以及网络犯罪的持续演变。 制裁俄罗斯洗钱人士 根据美国财政…

20231108在Ubuntu22.04下编译安装cmake-3.27.7.tar.gz

20231108在Ubuntu22.04下编译安装cmake-3.27.7.tar.gz 2023/11/8 17:28 缘起,编译cv180zb的时候提示说cmake的版本低! OBJCOPY platform/generic/firmware/payloads/test.bin OBJCOPY platform/generic/firmware/fw_dynamic.bin OBJCOPY platfor…

【AntDesign】Docker部署

docker部署是主流的部署方式,极大的方便了开发部署环境,保持了环境的统一,也是实现自动化部署的前提。 1 项目的目录结构 dist: 使用build打包命令,生成的打包目录 npm run build : 打包项目命令 docker: 存放docker容器需要修改…

2023年11月IDE流行度最新排名

点击查看最新IDE流行度最新排名(每月更新) 2023年11月IDE流行度最新排名 顶级IDE排名是通过分析在谷歌上搜索IDE下载页面的频率而创建的 一个IDE被搜索的次数越多,这个IDE就被认为越受欢迎。原始数据来自谷歌Trends 如果您相信集体智慧&am…

串口中断(10)自定义通讯协议-协议带数据长度及接收应答处理

本文为博主 日月同辉,与我共生,csdn原创首发。希望看完后能对你有所帮助,不足之处请指正!一起交流学习,共同进步! > 发布人:日月同辉,与我共生_单片机-CSDN博客 > 欢迎你为独创博主日月同…

2023年11月数据库流行度最新排名

点击查看最新数据库流行度最新排名(每月更新) 2023年11月数据库流行度最新排名 TOP DB顶级数据库索引是通过分析在谷歌上搜索数据库名称的频率来创建的 一个数据库被搜索的次数越多,这个数据库就被认为越受欢迎。这是一个领先指标。原始数…

微信小程序登录后端

一、 概念 code code是用户登录凭证,个人理解为用户的授权码(需要用户本人授权给小程序,小程序才有权力获取到你这个用户的数据),code需要由小程序向微信服务器获取。 注意: 每个code只能使用一次,且有效…

射频功率放大器应用中GaN HEMT的表面电势模型

标题:A surface-potential based model for GaN HEMTs in RF power amplifier applications 来源:IEEE IEDM 2010 本文中的任何第一人称都为论文的直译 摘要:我们提出了第一个基于表面电位的射频GaN HEMTs紧凑模型,并将我们的工…

kubernetes集群编排——k8s认证授权

pod绑定sa [rootk8s2 ~]# kubectl create sa admin [rootk8s2 secret]# vim pod5.yaml apiVersion: v1 kind: Pod metadata:name: mypod spec:serviceAccountName: admincontainers:- name: nginximage: nginxkubectl apply -f pod5.yamlkubectl get pod -o yaml 认证 [rootk8s…

SpringBoot案例学习(黑马程序员day10,day11)

1 环境准备&#xff1a; 1.idea 创建spring项目&#xff0c;选择springweb,mybatis framework ,sql drive框架 2.添加pom.xml依赖&#xff1a; <dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></dependen…

关于 pthread_create 传参的疑问

对于函数原型 int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine) (void *), void *arg) 里的参数 arg&#xff0c;之前一直有疑问&#xff0c;就是把 &thread 传给 arg时&#xff0c;新创建的线程里是否能取到这个值呢&#xff1…

小程序多文件上传 Tdesign

众所周知&#xff0c;小程序文件上传还是有点麻烦的&#xff0c;其实主要还是小程序对的接口有诸多的不便&#xff0c;比如说&#xff0c;文件不能批量提交&#xff0c;只能一个个的提交&#xff0c;小程序的上传需要专门的接口。 普通的小程序的页面也比普通的HTML复杂很多 现…