TextView 中确定 ClickableSpan 的具体位置

Android lineSpacingExtra 解决行间距兼容性问题 当我们使用TextView显示多行的文字或者单行时,为了美观,一般会加上行间距,这时就会用到lineSpacingExtra这个属性。 Android 5.0以下,在这个系统里面会添加一个行间距,导致多余空白。 Adnroid 5.0以上,google修复这个问题,但是由于厂商定制不一样,导致一些5.1版本的手机也会出现同样的问题,oppo等 解决思路: 1.需要理解... 阅读详情

现在有一个需求是 TextView 中要有特殊的字符加颜色还需要可以点击弹出pop,点击跳转和改变颜色 这个需求 ClickableSpan 就可以胜任。但是找到具体位置就有点困难。

这里写图片描述


1.确定 ClickableSpan 的具体位置

注意 需要 加上 textView.setMovementMethod(LinkMovementMethod.getInstance());表示可以点击的

SpannableString ssb = new SpannableString("xxxxx");
ssb.setSpan(new ClickableSpan() {
                    @Override
                    public void onClick(View widget) {
                        TextView parentTextView = (TextView) widget;
                        Rect parentTextViewRect = new Rect();

                        // Initialize values for the computing of clickedText position
                        SpannableString completeText = (SpannableString)(parentTextView).getText();
                        Layout textViewLayout = parentTextView.getLayout();

                        double startOffsetOfClickedText = completeText.getSpanStart(this);
                        double endOffsetOfClickedText = completeText.getSpanEnd(this);

                        double startXCoordinatesOfClickedText = textViewLayout.getPrimaryHorizontal((int)startOffsetOfClickedText);
                        double endXCoordinatesOfClickedText = textViewLayout.getPrimaryHorizontal((int)endOffsetOfClickedText);

                        // Get the rectangle of the clicked text
                        int currentLineStartOffset = textViewLayout.getLineForOffset((int)startOffsetOfClickedText);
                        int currentLineEndOffset = textViewLayout.getLineForOffset((int)endOffsetOfClickedText);

                        boolean keywordIsInMultiLine = currentLineStartOffset != currentLineEndOffset;
                        textViewLayout.getLineBounds(currentLineStartOffset, parentTextViewRect);

                        // Update the rectangle position to his real position on screen
                        int[] parentTextViewLocation = {0,0};
                        parentTextView.getLocationOnScreen(parentTextViewLocation);

                        double parentTextViewTopAndBottomOffset = (
                                parentTextViewLocation[1] -
                                        parentTextView.getScrollY() +
                                        parentTextView.getCompoundPaddingTop()
                        );

                        parentTextViewRect.top += parentTextViewTopAndBottomOffset;
                        parentTextViewRect.bottom += parentTextViewTopAndBottomOffset;

                        parentTextViewRect.left += (
                                parentTextViewLocation[0] +
                                        startXCoordinatesOfClickedText +
                                        parentTextView.getCompoundPaddingLeft() -
                                        parentTextView.getScrollX()
                        );
                        parentTextViewRect.right = (int) (
                                parentTextViewRect.left +
                                        endXCoordinatesOfClickedText -
                                        startXCoordinatesOfClickedText
                        );

                        int x = (parentTextViewRect.left + parentTextViewRect.right) / 2;
                        int y = parentTextViewRect.bottom;
                        if (keywordIsInMultiLine) {
                            x = parentTextViewRect.left;
                        }

                        spanTextLeft = x;
                        spanTextTop = parentTextViewRect.top;
                        spanTextBottom = y;

                        ///显示弹出层
                        showSubTitlePop(widget,name,stockid.toUpperCase());

                    }

                    @Override
                    public void updateDrawState(TextPaint ds) {
                        super.updateDrawState(ds);
                           ds.setColor(xxxx); // 设置文本颜色
                           // 去掉下划线
                          ds.setUnderlineText(false);
                    }
                }, start, start + name.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);

注意点:

1.double startOffsetOfClickedText = completeText.getSpanStart(this);
这个this是 ClickableSpan onclick 里面的this,其他的 this 是获取不到具体的值得。
2. x,y 就是最终 左边距和上边距,获取的是全屏的具体距离不是相对 textView 的


2.参考资料

How get coordinate of a ClickableSpan inside a TextView?

http://stackoverflow.com/questions/11905486/how-get-coordinate-of-a-clickablespan-inside-a-textview

Android TextView视觉定制全解析:从核心属性到性能优化实战 在Android应用开发中,UI控件的视觉定制是构建良好用户体验的基础。TextView作为最核心的文本显示组件,其渲染机制涉及系统主题、资源配置与设备密度等多重因素。理解其工作原理,掌握内容、字体、颜色与背景四大属性的正确配置方法,是实现界面美观、性能高效的关键。通过资源文件管理字符串与颜色,使用sp单位适配字体大小,并利用ColorStateList与Shape Drawable处理状态与背景,不仅能提升开发效率,还能确保应用在不同设备与主题下的兼容性。本文聚焦TextView的深度定制,结合国际化、深 阅读详情

相关推荐

AI大模型驱动的智能座舱研发体系重构

AI大模型正重构智能座舱研发体系的核心逻辑,需以场景认知为起点、混合架构为支柱、AI原生生态为落脚点。未来,研发体系需持续融合认知科学、边缘计算与开放生态理论,推动座舱从“工具”进化为“伙伴”。

我的专栏 1916

Android TextView获取ClickSpan点击位置的方法

2019独角兽企业重金招聘Python工程师标准>>> ...

weixin_34384681的博客 955

Infinite-Canvas:一站式AI绘画工作流平台部署与实战指南

在 AI 绘画和内容创作领域,你是否经常遇到这样的困扰:灵感来了,却要在多个工具间来回切换——找素材、写提示词、调整参数、批量生成,整个过程繁琐且低效。创作一个系列作品时,管理不同版本的图片和提示词更是让人头疼。如果你渴望一个能整合所有流程,实现从素材管理、提示词工程到批量出图一站式完成的工作台,那么今天介绍的 Infinite-Canvas 正是为你量身打造的解决方案。 Infinite-Canvas 是一个开源的本地网页应用,它将 AI 绘画的完整工作流集成在一个界面中。无论你是想快速生成单张图片,还是

weixin_28707535的博客 339

TextView使用ClickableSpan点击空白处也响应点击事件

1、ClickableSpan的使用 下面方法给字符串中数字添加点击事件: private SpannableString spannableText(String text){ if(TextUtils.isEmpty(text)){ return SpannableString.valueOf(""); } Pattern p = Pattern.compile("(120)|(110)|(119)|(122)...

aianzxy的博客 792

PID算法(位置式pid算法和增量式pid算法)

PID 算法是闭环控制系统中常用的算法,PID 分别是 Proportion(比例)、Integral(积分)、Differential(微分)的首字母缩写。它是一种结合比例、积分和微分三个环节于一体的闭环控。

m0_57678852的博客 2万+

Oracle VM VirtualBox虚拟机网络配置与静态IP设置实战

本文详细讲解了Oracle VM VirtualBox虚拟机的网络配置,特别是如何设置静态IP以实现稳定访问。文章对比了NAT、桥接、仅主机等网络模式,并提供了从VirtualBox管理界面到Linux系统内部的完整配置步骤,帮助用户解决IP变动问题,构建可靠的本地开发测试环境。

weixin_28365523的博客 511

TextView内部类Layout光标相关方法

使用TextView自定义EditView时,需要自己去维护光标位置,用到一些方法,简单的介绍下:1.获取行数getLineCount()2.获取指定行边界getLineBounds(int line, Rect bounds)获取该行的外包矩形bounds, 字符的顶部Y坐标就是rect的top 底部Y坐标就是rect的bottom3.根据坐标找到对应行getLineForVertical(int

猫的阁楼 2709

红外避障模块介绍

该传感器模块对环境光线适应能力强,其具有一对红外线发射与接收管,发射管发射出一定频率的红外线,当检测方向遇到障碍物(反射面)时,红外线反射回来被接收管接收,经过比较器电路处理之后,绿色指示灯会亮起,同时信号输出接回输出数字信号(一个低电平信号),可通过电位器旋钮调节检测距离,有效距离范围2~30cm,工作电压为3.3v-5v。该模块测距离2~~30cm,检测角度35°,检测距离可以通过电位器进行调节,顺时针调电位器,检测距离增加;1.VCC外接3.3v-5v电压(可以直接与5v单片机和3.3v单片机相连).

weixin_46251230的博客 2万+

android textview 点选单词,确定在android textview中单击了哪个单词

基本上,我想显示一段文本(可能是相当长的文本),并允许用户点击任何单词。 那时,我想确定他们点击了哪个单词。 我还想得到单词出现的整个句子(这是非常简单的,假设我可以确定单词在文本中的位置)。理想情况下,我只是听一个onTouch事件,得到X和Y,并说一些像textView.wordAt(event.x, event.y)或textView.cursorPositionNearest(event....

weixin_29903713的博客 415

Unity音游开发全指南:模板与免费资源高效构建节奏游戏

**粒子特效** | [Universal VFX](https://assetstore.unity.com/packages/vfx/particles/universal-vfx-159182) | 免费视觉特效 || **UI素材** | [Game UI Pack](https://assetstore.unity.com/packages/2d/gui/game-ui-pack-86908) | 现代风格UI元素 |**音游开发的黄金法则**:完美的节奏游戏是音乐与游戏的和谐统一。

Loving_enjoy的博客 730

【CAD】【手把手带你写一个DXF&JAVA解析框架】02——整理DXF元数据实体类,涵盖重要属性与对照组码

本文系统梳理了DXF文件解析中的核心元数据类,重点分析了Tables段(图层、块记录)、Blocks段和Entities段的关键数据结构。通过详细的组码说明和对照代码实现,阐述了图层定义(DXFLayer)、块记录(DXFBlockRecord)、应用程序标识(DXFAppId)等表对象的属性构成;同时解析了直线(DXFLine)、多段线(DXFLwPolyLine)、圆弧(DXFArc)、文字(DXFText)等实体类的几何特征与属性定义。文章还构建了顶点(Vertex)、基类(DXFEntity、DXF

Wonder ZH 270

TextView使用细节处理

问题描述: 当TextView使用ClickableSpan实现部分文字可点击的时候,倘若TextView的大小大于所显示的文字的时候,点击空白处也会触发点击事件。UI效果如下: 如图所示,可以看到框中的TextView的大小是明显大于所显示的文字的,如果给蓝色字体设置ClickableSpan点击事件的话,那么点击下面和右面的空白处也会触发点击事件的。 解决办法如下: 1、用LinearLay...

Mr_Tony的专栏 1172

TurboQuant: Online Vector Quantization with Near-optimal Distortion Rate

这篇被 ICLR 2026 接收的论文提出了一种名为TurboQuant的全新在线向量量化(Vector Quantization, VQ)算法。该研究的核心目标是解决大语言模型(LLM)在长上下文推理时面临的 KV Cache 显存消耗瓶颈,以及大规模向量数据库在近似最近邻检索中的存储与延迟问题。有别于现有技术,TurboQuant 是一种无需任何校准数据、无需训练的在线算法(Data-oblivious)。

c_cpp_csharp的专栏 118

Android TextView 富文本之 android.text.style.xxxSpan

前言 最近一直在做 TextView 富文本处理的工作,接触到了比较纤细的粗、字体颜色、内联图片、处理 ellipsize、LinkMovementMethod 的坑和ClickableSpan 的点击事件等问题,经过查资料、看源码和做实验三连之后,对 Android TextView 的富文本处理有了小小的体会,写篇博客总结下自己的收获,日后在遇到类似问题也方便回顾。 android.text....

funnywolfdadada的博客 758

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

Android TextView多颜色文本实现与优化

在Android UI开发中,文本样式定制是提升用户体验的关键技术。通过SpannableString机制,开发者可以在单个TextView中实现多颜色、多风格的富文本渲染,其底层原理是基于Span标记的文本片段级样式控制。这种技术不仅能减少视图层级提升性能(实测100个颜色片段仍保持60fps),更在电商价格展示、聊天消息高亮等场景有重要应用价值。针对实际开发中的中文计算、点击冲突等典型问题,需要掌握ForegroundColorSpan的精确定位技巧和SpannableStringBuilder的组合使

weixin_30319153的博客 368

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

android点击改变字体颜色,Android Textview 动态 部分文字点击 改变颜色

最近现在项目中遇到了一个需求 ,就是部分文字可以点击和改变颜色 ,这其实还是ok的 不是什么变态需求 因为也没有做过 我感觉textview 自己就会有实现此需求的办法 一百度还真有废话不多说 开始上代码public class MainActivity extends AppCompatActivity {@Overrideprotected void onCreate(Bundl...

weixin_42337065的博客 486

Outlook Express 6 (OE6) for Win7/Win8/Win10

英文版 Outlook Express6.0, 兼容Win7/Win10/WinXP,解压就可用。

设置TextView中超链接字体颜色、下划线

ClickableSpan:这是超链接相关的样式控制和点击事件的控制类,我们需要对它进行继承,然后修改成我们需要的样式。其中,可以对超链接文本字符进行颜色、字体大小、字体、下划线、点击事件的自定义控制。 上代码: public class PhoneClickSpan extends ClickableSpan { public interface OnLinkClickList

文韬武略的专栏 4386

Android可点击不定长度的TextView

如果要写一个横向的品牌列表,因为字数不确定,还需要加上点击效果,单纯的TextView就不能满足了,这时候可以重写ClickableSpan 使用方法: 1 public class MyClickableSpan extends android.text.style.ClickableSpan { 2 private final String mAction; 3 ...

weixin_33766168的博客 97

给TextView添加部分内容可点击的两种实现方式

第一种: //点击后的背景颜色(HighLightColor)属于TextView的属性,//Android4.0以上默认是淡绿色,低版本的是黄色。解决方法就是通过重新设置文字背景为透明色 textView.setHighlightColor(getResources().getColor(android.R.color.transparent)); SpannableString span...

ZhangXuxiaoqingnian的博客 2176

Android Textview 动态 部分文字点击 改变颜色

最近现在项目中遇到了一个需求 ,就是部分文字可以点击和改变颜色 ,这其实还是ok的  不是什么变态需求  因为也没有做过   我感觉textview 自己就会有实现此需求的办法   一百度还真有 废话不多说  开始上代码 public class MainActivity extends AppCompatActivity {     @Override     protected void...

那些回不去的年少无知 1309

安卓给TextView几个字段设置点击事件

最近需要给TextView的几个字段设置设置点击事件,这个应该是很普遍的,也很容易实现的,但是百度了好久都是千篇一律的,设置的开始跟结束位置都是固定写死的必然要(0,5)这样设参,而且不灵活。需要用到的组件有SpannableString,这个组件也有个getSpanStart()跟getSpanEnd()两个方法,这两个开始跟结束的位置怎么使用还不会,一直报空,然后采用比较笨拙的方法,就是将数据

Never_said_No的专栏 1600

android开发游记:textview超过长度点击展开自动滚动(在一个TextView中实现,不增加布局复杂度)

最近有需求需要在一个有限高度的页面上显示超过其高度的文字,当文字超过最大行之后显示省略号和查看更多,然后点击查看更多显示完整的信息,并且可以滚动。 先看效果图: 功能很简单,网上搜的有人使用了scrollview来滚动,再添加一个按钮”查看更多”,然后点击后把消息全部展示,再把按钮隐藏。 但是这样做不是觉得很复杂,其实所有的工作在一个textView里就可以完成了,包括滚

u012426327的专栏 1266

Android实现部分文字可点击及变色

可以使用SpannableString和ClickableSpan: TextView userAgreement = findViewById(R.id.user_agreement); SpannableString agreement = new SpannableString("Agree to the User Agreement and Privac...

Joven0的专栏 1782
上一篇: picasso 显示本地图片
下一篇: WebView 加载https 白屏以及重定向加载
android_小路
博客等级 码龄12年 53粉丝 46原创
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值