android-自定义TextView在文字内容末尾添加图片icon、可以添加间距

样式示意图

样式示意图

自定义属性 style.xml

    <declare-styleable name="IconLabelTextView"><attr name="iconSrc" format="reference"/><attr name="iconPaddingStart" format="dimension"/><attr name="iconPaddingTop" format="dimension"/><attr name="iconPaddingBottom" format="dimension"/></declare-styleable>

自定义View-IconLabelTextView代码片段

import android.content.Context
import android.graphics.Canvas
import android.graphics.drawable.Drawable
import android.text.Layout
import android.text.StaticLayout
import android.text.TextPaint
import android.util.AttributeSet
import androidx.appcompat.widget.AppCompatTextView
import com.foreo.common.utils.DensityUtils
import com.xyz.Rclass IconLabelTextView : AppCompatTextView {private var icon: Drawable? = nullprivate var iconPaddingStart: Int = 0private var iconPaddingTop: Int = 0private var iconPaddingBottom: Int = 0constructor(context: Context) : super(context) {init(null)}constructor(context: Context, attrs: AttributeSet?) : super(context, attrs) {init(attrs)}constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(context,attrs,defStyleAttr) {init(attrs)}private fun init(attrs: AttributeSet?) {val a = context.obtainStyledAttributes(attrs, R.styleable.IconLabelTextView)icon = a.getDrawable(R.styleable.IconLabelTextView_iconSrc)iconPaddingStart = a.getDimensionPixelSize(R.styleable.IconLabelTextView_iconPaddingStart, 0)iconPaddingTop = a.getDimensionPixelSize(R.styleable.IconLabelTextView_iconPaddingTop, 0)iconPaddingBottom = a.getDimensionPixelSize(R.styleable.IconLabelTextView_iconPaddingBottom, 0)a.recycle()}override fun onDraw(canvas: Canvas?) {super.onDraw(canvas)canvas?.let { canvas ->val textPaint: TextPaint = paintval lineHeight = textPaint.descent() - textPaint.ascent()val lineCount = layout.lineCountval paddingTop = paddingTop.toFloat()val availableWidth = width - paddingLeft - paddingRight - DensityUtils.dp2px(30)val layout = layout ?: return@letfor (i in 0 until lineCount) {val lineStart = layout.getLineStart(i)val lineEnd = layout.getLineEnd(i)val lineText = text.subSequence(lineStart, lineEnd).toString()if (i == lineCount - 1 && layout.getLineWidth(i) >= availableWidth) {// last line with maxLines and text filled completely, adjust text to fit iconvar adjustedText = lineTextvar textWidth = textPaint.measureText(lineText)val iconWidth = icon?.intrinsicWidth ?: 0while (textWidth + iconWidth + iconPaddingStart > availableWidth) {adjustedText = adjustedText.substring(0, adjustedText.length - 1)textWidth = textPaint.measureText(adjustedText)}if (!adjustedText.isNullOrBlank() && lineText != adjustedText) {val splitIndex = text.indexOf(adjustedText) + adjustedText.lengthtext?.substring(0, splitIndex)?.let { text = "$it..." }return}if (adjustedText.isNotEmpty()) {val staticLayout = StaticLayout(adjustedText,textPaint,availableWidth.toInt(),Layout.Alignment.ALIGN_NORMAL,1f,0f,false)val iconY =paddingTop + (lineHeight * i) + (lineHeight - (icon?.intrinsicHeight?: 0)) / 2 + iconPaddingTop - iconPaddingBottomval iconX = paddingLeft + staticLayout.width + iconPaddingStarticon?.setBounds(iconX.toInt(),iconY.toInt(),(iconX + iconWidth).toInt(),(iconY + (icon?.intrinsicHeight ?: 0)).toInt())icon?.draw(canvas)}} else if (i == lineCount - 1 && lineEnd <= text.length) {// last line, add iconicon?.let {val textWidth = textPaint.measureText(lineText)val iconY =paddingTop + (lineHeight * i) + (lineHeight - it.intrinsicHeight) / 2 + iconPaddingTop - iconPaddingBottomval iconX = paddingLeft + textWidth + iconPaddingStartit.setBounds(iconX.toInt(),iconY.toInt(),(iconX + it.intrinsicWidth).toInt(),(iconY + it.intrinsicHeight).toInt())it.draw(canvas)}}}}}fun setIcon(icon: Drawable?, paddingStart: Int, paddingTop: Int, paddingBottom: Int) {this.icon = iconthis.iconPaddingStart = paddingStartthis.iconPaddingTop = paddingTopthis.iconPaddingBottom = paddingBottominvalidate()}
}

xml中使用

  <com.xyz.IconLabelTextViewandroid:id="@+id/productVariation"android:layout_width="match_parent"android:layout_height="wrap_content"android:ellipsize="end"android:maxLines="2"android:textSize="12sp"app:iconPaddingBottom="0dp"app:iconPaddingStart="5dp"app:iconPaddingTop="3dp"app:iconSrc="@drawable/ic_arrow_down_cart"tools:text="Normal Skin" />

代码中使用

productVariation.setIcon(getDrawable(R.drawable.ic_arrow_down_cart),10,0,0)

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

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

相关文章

访问网站显示不安全是什么原因?怎么解决?

访问网站时显示“不安全”&#xff0c;主要原因以及解决办法&#xff1a; 1.没用HTTPS加密&#xff1a;网站还在用老的HTTP协议&#xff0c;数据传输没加密&#xff0c;容易被人偷看或篡改。解决办法是网站管理员启用HTTPS&#xff0c;也就是给网站装个“SSL证书”。这个是最常…

模块十三 异常_Object

回顾与重点 模块十二回顾 权限修饰符&#xff1a; public → protected → 默认 → private a. 构造一般用public&#xff1a;便于new对象 b. 成员方法一般用public&#xff1a;便于调用 c. 属性一般用private&#xff1a;封装思想 final&#xff1a;最终的 a. 修饰类&#x…

k8s_入门_kubelet安装

安装 在大致了解了一些k8s的基本概念之后&#xff0c;我们实际部署一个k8s集群&#xff0c;做进一步的了解 1. 裸机安装 采用三台机器&#xff0c;一台机器为Master&#xff08;控制面板组件&#xff09;两台机器为Node&#xff08;工作节点&#xff09; 机器的准备有两种方式…

前端开发之el-table(vue2中)固定列fixed滚动条被固定列盖住

固定列fixed滚动条被固定列盖住 效果图前言解决方案 效果图 前言 在使用fixed固定列的时候会出现滚动条被盖住的情况 解决方案 改变el-table固定列的计算高度即可 .el-table {.el-table__fixed-right,.el-table__fixed {height:auto !important;bottom:15px !important;}}

数据结构(七)——查找的基本概念

七、查找 7.1 查找的基本概念 7.1.1 基本概念 查找 —— 在数据集合中寻找满⾜某种条件的数据元素的过程称为查找 查找表&#xff08;查找结构&#xff09;—— ⽤于查找的数据集合称为查找表&#xff0c;它由同⼀类型的数据元素&#xff08;或记录&#xff09;组成 关键字 …

Golang | Leetcode Golang题解之第18题四数之和

题目&#xff1a; 题解&#xff1a; func fourSum(nums []int, target int) (quadruplets [][]int) {sort.Ints(nums)n : len(nums)for i : 0; i < n-3 && nums[i]nums[i1]nums[i2]nums[i3] < target; i {if i > 0 && nums[i] nums[i-1] || nums[i]…

数字化智慧养老:引领老年人融入科技时代新生活

hello宝子们...我们是艾斯视觉擅长ui设计和前端开发10年经验&#xff01;希望我的分享能帮助到您&#xff01;如需帮助可以评论关注私信我们一起探讨&#xff01;致敬感谢感恩&#xff01; 人类社会已经步入了一个全新的数字时代。在这个时代&#xff0c;互联网、大数据、人工智…

PDF锐化

PDF Shaper Ultimate(pdf转图片) 编辑->添加文件->选中一个要处理的pdf 操作->转换->PDF转为图片 ComicEnhancerPro设置(把图片锐化) PDF Shaper Ultimate(图片转pdf) 编辑-添加图片->选中所有锐化处理后的图片 转换->图片转为pdf&#xff08;会把所有图…

全国火情预报卫星遥感应用方案

一、引言 火情预报应急卫星遥感解决方案是一种利用卫星遥感技术进行火灾预警和应急响应的方法。该方案通过实时监测和分析森林、草原等地区的火情信息&#xff0c;为火灾预警和应急响应提供科学依据&#xff0c;有效减少火灾造成的损失。本技术文档将介绍火情预报应急卫…

Java | Leetcode Java题解之第18题四数之和

题目&#xff1a; 题解&#xff1a; class Solution {public List<List<Integer>> fourSum(int[] nums, int target) {List<List<Integer>> quadruplets new ArrayList<List<Integer>>();if (nums null || nums.length < 4) {return…

el-cascader的懒加载模式怎么设置默认值

点击修改会跳出一个dialog&#xff0c;dialog需要显示信息&#xff0c;其中地址使用el-cascader标签并使用懒加载实现&#xff0c;地址数据都是从后台获取&#xff0c;如果直接使用v-model绑定默认值&#xff0c;会不显示。 解决方法1&#xff1a; <el-cascader class&quo…

React - 请你说一说setState是同步的还是异步的

难度级别:中高级及以上 提问概率:70% 在React项目中,使用setState可以更新状态数据,而不能直接使用为this.state赋值的方式。而为了避免重复更新state数据,React首先将state添加到状态队列中,此时我们可以通过shouldComponentUpdate这个钩…

Python编程启航:大学生如何用代码编织未来

开篇 掌握Python&#xff0c;打开编程世界的大门&#xff01;作为一名大学生&#xff0c;你是否渴望在编程的海洋中遨游&#xff0c;用代码编织未来&#xff1f; &#x1f31f;&#x1f680;现在就跟随我一起&#xff0c;探索Python编程的奇妙之旅&#xff0c;解锁学习技巧、…

数据库——实验6 视图的创建与使用

1. 视图的定义 视图是根据需要以一个表或多个表为基础&#xff0c;选择满足一定条件的行或列数据的静态定义。它是一种逻辑对象&#xff0c;是一种虚拟表。视图并不生成行或列的永久副本&#xff0c;并不占用存储空 间&#xff0c;也就是说&#xff0c;视图就是保存在数据库中…

加州大学欧文分校英语基础语法专项课程03:Simple Past Tense 学习笔记(完结)

Learn English: Beginning Grammar Specialization Specialization Certificate course 3&#xff1a; Simple Past Tense Course Certificate 本文是学习 https://www.coursera.org/learn/simple-past-tense 这门课的学习笔记&#xff0c;如有侵权&#xff0c;请联系删除。…

函数重载和引用【C++】

文章目录 函数重载什么是函数重载&#xff1f;函数重载的作用使用函数重载的注意点为什么C可以函数重载&#xff0c;C语言不行&#xff1f; 引用什么是引用&#xff1f;引用的语法引用的特点引用的使用场景引用的底层实现传参时传引用和传值的效率引用和指针的区别 函数重载 什…

OpenHarmony实战:物联网解决方案之芯海cst85芯片移植案例

本文介绍基于芯海cst85芯片的cst85_wblink开发板移植OpenHarmony LiteOS-M轻量系统的移植案例。 开发了Wi-Fi连接样例和XTS测试样例&#xff0c;同时实现了wifi_lite, lwip, startup, utils, xts, hdf等部件基于OpenHarmony LiteOS-M内核的适配。 移植架构上采用Board和Soc分…

ArcGIS和ArcGIS Pro快速加载ArcGIS历史影像World Imagery Wayback

ArcGIS在线历史影像网站 World Imagery Wayback(网址:https://livingatlas.arcgis.com/wayback/)提供了数期历史影像在线浏览服务,之前不少自媒体作者在文中宣称其能代表Google Earth历史影像。 1、一点对比 (1)同一级别下的版本覆盖面 以下述区域为例,自2014年2月20…

【随笔】Git 基础篇 -- 分支与合并 git rebase(十)

&#x1f48c; 所属专栏&#xff1a;【Git】 &#x1f600; 作  者&#xff1a;我是夜阑的狗&#x1f436; &#x1f680; 个人简介&#xff1a;一个正在努力学技术的CV工程师&#xff0c;专注基础和实战分享 &#xff0c;欢迎咨询&#xff01; &#x1f496; 欢迎大…

GFS分布式 文件系统

一、GFS的概念 文件存储分为nfs、lvm、raid 对象存储分为GFS、CEPH、fastDFS&#xff08;分布式文件存储&#xff09;NAS OSS S3 switch OSS 属于阿里云 通过URL 链接 S3属于亚马逊通过URL链接 1.1 GFS简介 开源的分布式文件系统&#xff0c;由存储服务器、客户端…