当前位置: 首页 > news >正文

【Android】Span富文本简介

一,概述

android.text包下span体系类,主要指Spanned、Spannable、ParagraphStyle、CharacterStyle实现类。Android通过Span体系,搭建了富文本API,其中Spanned、Spannable实现了CharSequence接口,旨在映射段落start~end之间Span装饰对象。Span对象大多实现ParagraphStyle、CharacterStyle两者之一,是装饰段落字符的对象,其中ParagraphStyle会影响layout,CharacterStyle只影响draw期间paint样式。

除此之外还存在MovementMethod接口代理解析touch事件。

以及Html工具类,通过html语言映射到原生Span接口。如下,

 Html.fromHtml("<p>这是</p>", Html.FROM_HTML_MODE_LEGACY)

Spannable核心实现类是SpannableStringBuilder,该类实现了setSpan、getSpan、removeSpan等方法,

通过map、数组,保存了段落到Span对象的映射。

Span对象ParagraphStyle、CharacterStyle实现类在android.text.style包下,如下,读者可自行查看

每个Span影响了字符样式或者段落位置,甚至可单独添加点击事件,如ClickableSpan。

二,实例

如下,简单对TextView设置一个下划线+可点击Span例子。

 findViewById<TextView>(R.id.span_text).apply {val spstr = SpannableStringBuilder("这是一段文字")spstr.setSpan(UnderlineSpan(),0,2, Spannable.SPAN_INCLUSIVE_INCLUSIVE)spstr.setSpan(object : ClickableSpan(){override fun onClick(widget: View) {Toast.makeText(this@SpanTestActivity,"Click ",Toast.LENGTH_SHORT).show()}override fun updateDrawState(ds: TextPaint) {super.updateDrawState(ds)ds.color = Color.BLUEds.isUnderlineText = false}},2,5, Spannable.SPAN_INCLUSIVE_INCLUSIVE)movementMethod = LinkMovementMethod.getInstance()highlightColor = Color.TRANSPARENTtext = spstr}

三,分析

1 ,setSpan

实现类是SpannableStringBuilder,在setSpan方法中,通过map、数组,将Span和段落之间现成映射,并且同一个Span对象不可复用在多个段落,以下逻辑确保了传入同一个Span时会更新start、end、flag数组,

跟进,如果传入一个新的Span对象,会把欧尼到mSpan*数组中,如下

通过GrowingArrayUtils#append工具类方法,确保了Span被安全添加至数组中,

调用restorInvariants方法,会重建索引树,即mIndexOfSpan。

明白了setSpan,那么getSpan以及removeSpan,便可知道其实现逻辑,不赘述了。

2,CharacterStyle

对于字符样式,在Android中是通过Paint控制,因此CharacterStyle有一个必须实现的接口方法,

CharacterStyle#updateDrawState,子类通过重写此模版方法,便可改变Paint属性,如Color等。读者可自定义一个Span实现CharacterStyle接口,便可做出更多自定义行为。

以ForegroundColorSpan为例,其updateDrawState方法调用了Paint#setColor而已,不赘述。

那么updateDrawState何时被调用呢?显而易见,在TextView#draw期间,通过dubug stack可清晰知道

3,ClickableSpan

ClickableSpan是对CharacterStyle接口实现的抽象类,新增了onClick方法,只在自定段落start~end被点击后,触发。

要实现ClickableSpan效果,还需要传递MovementMethod接口实现类给到TextView,通过setMovementMethod方法即可,

MovementMethod接口hook了touch事件过程,可逐个对字符实现touch事件分发。LinkMovementMethod实现类新增解析ClickableSpan逻辑,即可触发其onClick方法,大致逻辑如下

touch事件识别选中的start和end,通过getSpans方法获得Span,如果存在ClickableSpan且为1情况下,触发onClick,否则忽略。

4,ParagraphStyle

ParagraphStyle拓展接口如下,均和Layout过程相关,在layout期间确立了边距,随后也会在draw期间调用draw相关模版方法,实现绘制drawable等操作,以DrawableMarginSpan为例

以上,即实现了文本中插入了drawble操作。

5,Html

对于简单富文本,通过setSpan方法还是稍许复杂,且可读性不高,因此span框架推出了Html工具类,可解析h5文本,将其转化为Span对象集合设置到TextView中。

以fromHtml为例,返回SPanned对象,此对象只可读取Span,不可编辑,即无setSpan方法。

跟进,

通过HtmlToSpannedConverer来实现转化,跟进convert

以上,解析h5节点,映射到SpannableStringBuilder对象返回即可,关于怎么解析不赘述。

http://www.xdnf.cn/news/1416385.html

相关文章:

  • Python 爬虫案例:爬取豆瓣电影 Top250 数据
  • 华为云CCE
  • 【Flask】测试平台开发,实现全局邮件发送工具 第十二篇
  • [免费]基于Python的气象天气预报数据可视化分析系统(Flask+echarts+爬虫) 【论文+源码+SQL脚本】
  • 【Proteus仿真】蜂鸣器控制系列仿真——蜂鸣器控制/蜂鸣器播放音乐/蜂鸣器播放多种音乐/蜂鸣器和LED组成报警装置
  • 如何在Github中创建仓库?如何将本地项目上传到GitHub中?
  • 【HTML】draggable 属性:解锁网页交互新维度
  • 深入探讨Java异常处理:受检异常与非受检异常的最佳实践
  • 领码方案:低代码平台前端缓存与 IndexedDB 智能组件深度实战
  • Eclipse Compiler for Java (ECJ):安装指南与高效快捷键全解析
  • 玩转OurBMC第二十一期:前端页面仪表盘的设计与使用实践
  • Trae x MCP:一键打造品牌专属高质量SVG封面
  • CompletableFuture初体验
  • (9.1)Python测试之记录
  • Shell 编程 —— 正则表达式与文本处理器
  • 函数,数组与正则表达式
  • Android原生HttpURLConnection上传图片方案
  • 打造智能写作工作流:n8n + 蓝耘MaaS平台完整实战指南
  • Apollo学习之决策模块
  • 【Linux手册】Unix/Linux 信号:原理、触发与响应机制实战
  • Ajax笔记(下)
  • 在.NET标准库中进行数据验证的方法
  • Java视觉跟踪入门:使用OpenCV实现实时对象追踪
  • 【开题答辩全过程】以 基于php的校园兼职求职网站为例,包含答辩的问题和答案
  • 【Android】使用Handler做多个线程之间的通信
  • 【Flask】测试平台开发,应用管理模块实现-第十一篇
  • 【lucene核心】impacts的由来
  • 旧物回收小程序:科技赋能,开启旧物新生之旅
  • 山东省信息技术应用创新开展进程(一)
  • 《C++进阶之STL》【红黑树】