当前位置: 首页 > 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.dtcms.com/a/361913.html

相关文章:

  • 苹果 Safari 地址栏可能被超大光标视觉欺骗
  • 阿里云OSS架构示意图与流程
  • AR眼镜在警务安防的应用方案
  • 前沿科技竞速:脑机接口、AI芯片与半导体生态上的新突破
  • 线性回归中梯度下降与正规方程以及拟合问题与正则化
  • 【职业】算法与数据结构专题
  • 【Flink】DataStream API (二)
  • 收藏!VSCode 开发者工具快捷键大全
  • 计算机毕设推荐:基于python的农产品价格数据分析与预测的可视化系统的设计与实现 基于Python农产品管理系统【源码+文档+调试】
  • 基于单片机汽车防盗系统/汽车安全防丢系统
  • 企业级主流日志系统架构对比ELKK Stack -Grafana Stack
  • 解决「图片导出功能需要 Chromium 浏览器支持,但未找到」的完整方案
  • Promise:异步编程的优雅解决方案
  • elemen ui Table表格中添加图片
  • qData 数据中台【开源版】发布 1.0.4 版本,全面升级数据清洗与资产管理能力
  • Spring Security(第六篇):结营篇 —— 完整源码与后续进阶路线 [特殊字符]
  • Day20 API
  • 什么是最大熵强化学习?
  • Go项目中关于优雅关闭的那些事
  • 动态配置最佳实践:Spring Boot 十种落地方式与回滚审计指南(含实操与避坑)
  • 如何将mysql数据导入人大金仓数据库
  • 漏洞挖掘 渗透测试思路图总结
  • 期货交易策略自动化实现
  • 数组基础及原理
  • 秋招冲刺计划(Day12)
  • Qwen-Image-Edit完全指南:实战20B参数模型的文字与语义-外观双重编辑
  • 如何使用VMware创建一台Ubuntu机器
  • Linux内核内存管理系列博客教程学习规划
  • KVM虚拟机快速安装与配置指南
  • leetcode算法day24