Android 神奇的 SpannableStringBuilder

news2025/1/17 1:16:58

文章目录

  • 前言
  • 一、SpannableStringBuilder 是什么?
  • 二、使用步骤
    • 1.示例代码
    • 2.参数对应
      • start:样式生效的开始位置,包括该位置
      • end: 样式结束的位置,不包括该位置
      • flags:取值有如下四个
        • Spannable.SPAN_EXCLUSIVE_INCLUSIVE
        • Spannable.SPAN_INCLUSIVE_EXCLUSIVE
        • Spannable.SPAN_INCUJSIVE_INCLUSIVE
        • Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
      • what:对应的各种Span
            • 1 BackgroundColorSpan : 背景色
            • 2 ForegroundColorSpan : 颜色
            • 3 RasterizerSpan : 光栅
            • 4 StrikethroughSpan : 删除线
            • 5 SuggestionSpan : 占位符
            • 6 UnderlineSpan : 下划线
            • 7 AbsoluteSizeSpan : 文本字体
            • 8 ImageSpan : 图片
            • 9 ScaleXSpan : 基于x轴文本水平缩放
            • 10 StyleSpan : 字体样式:粗体、斜体等
            • 11 SubscriptSpan : 下标
            • 12 SuperscriptSpan : 上标
            • 13 TypefaceSpan : 字体样式
            • 14 URLSpan : 超链接
            • 15 ClickableSpan : 点击事件
            • 16 AbsoluteSizeSpan 字体大小
    • 3.SpannableStringBuilder 基础样式示例
            • 1 加粗
            • 2 斜体
            • 3 加粗并斜体
            • 4 删除线
            • 5 下划线
            • 6 字体颜色
            • 7 背景颜色
            • 8 文本大小
            • 9 超链接
            • 10 图片
            • 11 文本水平缩放
            • 12 字体样式
            • 13 行高
            • 14 字符间距
  • 三、SpannableStringBuilder 自定义样式
          • 自定义span 文本模糊
          • 自定义span 文本背景颜色
          • 自定义span 文本阴影
          • 自定义span 文本描边
  • 总结


前言

今天为什么要说 SpannableStringBuilder 这个类呢 ,这还要从之前悲催的项目经历说起,原型是这样子的,我们主要看文本,其余暂时忽略
在这里插入图片描述当你看到图,是不是感觉很熟悉,因为他就是个服务条款跟隐私政策一样的勾选提交功能,如果不出意外的话,TextView 文本拼接,然后再添加上点击事件跳转,大功告成,但往往这时候都会出意外,这个服务条款很隐私政策是接口动态获取的,可能是一个也可能是两个,但此时我告诉你一个 TextView 即可搞定是不是很神奇?来看下本章最终的实现效果
在这里插入图片描述
Demo 源码在文章最底部,文章很长,要耐心哦

一、SpannableStringBuilder 是什么?

Google 官方的介绍已经很直白了,翻译过来就是,这是用于内容和标记都可以更改的文本的类。是不是第一时间想到了富文本,没错,它就是 Android 中用于创建富文本的类,它是 Spannable 接口的实现类,可以在文本中添加样式、图片、超链接等效果。

SpannableStringBuilder 和 StringBuilder 类似,也是一个动态字符串类,支持插入和删除文本,但是它可以在文本中添加多种样式,
在这里插入图片描述
通过源码我们可以得知,SpannableStringBuilder 主要实现了 CharSequence 和 Spannable 接口,
在这里插入图片描述CharSequence 接口是在 Java 中定义的一个字符序列接口,它表示一个字符序列,可以是 String、StringBuilder、StringBuffer 等类型。CharSequence 接口是一个只读接口,提供了以下方法:

charAt(int index):返回指定位置的字符。
length():返回字符序列的长度。
subSequence(int start, int end):返回从 start 到 end-1 的字符序列子序列。
toString():返回字符序列的字符串表示形式。

CharSequence 接口的作用是为了实现字符序列的多态。通过实现该接口,不同的字符序列类型可以使用相同的方法,从而方便编程和提高代码的可读性。例如,当方法需要一个 CharSequence 类型的参数时,可以传递任何实现了 CharSequence 接口的类的对象。

在 Android 中,CharSequence 接口被广泛使用。使用 CharSequence 接口可以使程序更加灵活,提高代码的可重用性。

在这里插入图片描述接着再看 Spannable 接口,通过 注释翻译过来就是标记对象可以指向的文本的接口,Spannable 接口定义了添加、移除、获取富文本样式的方法,

setSpan(Object what, int start, int end, int flags):添加一个样式 what 到 start 到 end 之间的文本中,flags 参数用于控制样式的行为。

removeSpan(Object what):从文本中移除指定的样式 what。

getSpans(int start, int end, Class<T> type):获取从 start 到 end 之间的文本中所有类型为 type 的样式。

使用 Spannable 接口可以实现很多应用场景,例如:富文本编辑器、聊天应用中的表情符号、高亮搜索关键字等等。它可以帮助程序员实现更好的用户交互体验,提高应用的质量和可用性。

在这里插入图片描述最后 我们看下主要的两个方法,这两个方法为富文本提供了实现

public SpannableStringBuilder append(CharSequence text) {}

该方法的作用是将一个字符序列 text 追加到 SpannableStringBuilder 实例的末尾,并返回追加后的 SpannableStringBuilder 对象
在这里插入图片描述public void setSpan(Object what, int start, int end, int flags) {}

通过翻译可知
用指定的对象标记指定的文本范围。标志确定当文本为。插入到跨度范围的开始或结束处。
在这里插入图片描述

二、使用步骤

1.示例代码

        SpannableStringBuilder builder1 = new SpannableStringBuilder();
        builder1.append("Hello World ! Do you like programming?"); // 添加普通文本
        builder1.setSpan(new StyleSpan(Typeface.BOLD), 0, 5, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); // 加粗
        builder1.setSpan(new ForegroundColorSpan(Color.RED), 6, 11, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); // 字体颜色
        builder1.setSpan(new UnderlineSpan(), 12, 17, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); // 下划线
        builder1.setSpan(new URLSpan("https://www.baidu.com"), 18, 28, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); // 超链接
        builder1.setSpan(new ImageSpan(this, R.mipmap.icon_pair_number), 29, 34, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); // 图片
        span1Tv.setText(builder1);

2.参数对应

start:样式生效的开始位置,包括该位置

end: 样式结束的位置,不包括该位置

 注意 :设置字符串前2个文字的样式为  start:0,end:2。而不是 end:1

flags:取值有如下四个

Spannable.SPAN_EXCLUSIVE_INCLUSIVE

  前面不包括,后面包括,在Span前面输入的字符不应用 span 的效果,在后面输入的字符应用Span效果。

Spannable.SPAN_INCLUSIVE_EXCLUSIVE

  前面包括,后面不包括,即在文本前插入新的文本会应用该样式,而在文本后插入新文本不会应用该样式

Spannable.SPAN_INCUJSIVE_INCLUSIVE

  前面包括,后面包括,即在文本前插入新的文本会应用该样式,而在文本后插入新文本也会应用该样式

Spannable.SPAN_EXCLUSIVE_EXCLUSIVE

  前面不包括,后面不包括,在 Span前后输入的字符前后都不应用 span 的效果

what:对应的各种Span

1 BackgroundColorSpan : 背景色
2 ForegroundColorSpan : 颜色
3 RasterizerSpan : 光栅
4 StrikethroughSpan : 删除线
5 SuggestionSpan : 占位符
6 UnderlineSpan : 下划线
7 AbsoluteSizeSpan : 文本字体
8 ImageSpan : 图片
9 ScaleXSpan : 基于x轴文本水平缩放
10 StyleSpan : 字体样式:粗体、斜体等
11 SubscriptSpan : 下标
12 SuperscriptSpan : 上标
13 TypefaceSpan : 字体样式
14 URLSpan : 超链接
15 ClickableSpan : 点击事件
16 AbsoluteSizeSpan 字体大小

3.SpannableStringBuilder 基础样式示例

1 加粗
builder.setSpan(new StyleSpan(Typeface.BOLD), start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
2 斜体
builder.setSpan(new StyleSpan(Typeface.ITALIC), start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
3 加粗并斜体
builder.setSpan(new StyleSpan(Typeface.BOLD_ITALIC), start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
4 删除线
builder.setSpan(new StrikethroughSpan(), start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
5 下划线
builder.setSpan(new UnderlineSpan(), start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
6 字体颜色
builder.setSpan(new ForegroundColorSpan(color), start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
7 背景颜色
builder.setSpan(new BackgroundColorSpan(color), start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
8 文本大小
builder.setSpan(new AbsoluteSizeSpan(sizeInPx), start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
9 超链接
builder.setSpan(new URLSpan(url), start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
10 图片
builder.setSpan(new ImageSpan(context, resourceId), start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
11 文本水平缩放
builder.setSpan(new ScaleXSpan(scale), start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
12 字体样式
builder.setSpan(new TypefaceSpan(typeface), start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
13 行高
builder.setSpan(new LineHeightSpan() {
    @Override
    public void chooseHeight(CharSequence text, int start, int end, int spanstartv, int v, Paint.FontMetricsInt fm) {
        fm.descent += lineHeight - fm.bottom;
        fm.bottom = lineHeight;
    }
}, start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
14 字符间距
builder.setSpan(new ScaleXSpan(spacing), start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);

三、SpannableStringBuilder 自定义样式

除了基础样式之外,您还可以自定义其它样式,例如:文本描边、文本模糊等等。只需要继承 CharacterStyle 类,并重写 updateDrawState() 方法即可。

自定义span 文本模糊
 在这个示例中,我们自定义了一个 BlurSpan 类型,用于设置文本模糊效果。它继承自 CharacterStyle 类,重写了 updateDrawState() 方法,在该方法中设置了文本的模糊效果。

 在 updateDrawState() 方法中,我们首先创建了一个 BlurMaskFilter 对象,该对象用于设置模糊半径和模糊类型。然后,我们使用 setMaskFilter() 方法设置文本的模糊效果。
/**
 * 自定义span 文本模糊
 */
public class BlurSpan extends CharacterStyle {

    private float mRadius;

    public BlurSpan(float radius) {
        this.mRadius = radius;
    }

    @Override
    public void updateDrawState(TextPaint tp) {
        tp.setMaskFilter(new BlurMaskFilter(mRadius, BlurMaskFilter.Blur.NORMAL));
    }
}
自定义span 文本背景颜色
在这个示例中,我们自定义了一个 CustomBackgroundColorSpan 类型,用于设置文本的背景颜色。它继承自 CharacterStyle 类,重写了 updateDrawState() 方法,在该方法中设置了文本的背景颜色。
public class CustomSpan extends CharacterStyle {

    private int mBackgroundColor;

    public CustomSpan(int backgroundColor) {
        this.mBackgroundColor = backgroundColor;
    }

    @Override
    public void updateDrawState(TextPaint tp) {
        tp.bgColor = mBackgroundColor;
    }
}
自定义span 文本阴影
 在这个示例中,我们自定义了一个 ShadowSpan 类型,用于设置文本阴影效果。它继承自 CharacterStyle 类,重写了 updateDrawState() 方法,在该方法中设置了文本的阴影效果。

 在 updateDrawState() 方法中,我们首先创建了一个阴影层,该层的半径、偏移量和颜色分别由 mRadius、mDx、mDy 和 mShadowColor 决定。然后,我们使用 setShadowLayer() 方法设置阴影效果。
public class ShadowSpan extends CharacterStyle {

    private float mRadius;
    private float mDx;
    private float mDy;
    private int mShadowColor;

    public ShadowSpan(float radius, float dx, float dy, int shadowColor) {
        this.mRadius = radius;
        this.mDx = dx;
        this.mDy = dy;
        this.mShadowColor = shadowColor;
    }

    @Override
    public void updateDrawState(TextPaint tp) {
        tp.setShadowLayer(mRadius, mDx, mDy, mShadowColor);
    }
}
自定义span 文本描边
 在这个示例中,我们自定义了一个 StrokeSpan 类型,用于设置文本描边效果。它继承自 CharacterStyle 类,重写了 updateDrawState() 方法,在该方法中设置了文本的描边效果。

 在 updateDrawState() 方法中,我们首先设置了文本的样式为描边样式,然后设置了描边宽度和描边颜色。
public class StrokeSpan extends CharacterStyle {

    private float mStrokeWidth;
    private int mStrokeColor;

    public StrokeSpan(float strokeWidth, int strokeColor) {
        this.mStrokeWidth = strokeWidth;
        this.mStrokeColor = strokeColor;
    }

    @Override
    public void updateDrawState(TextPaint tp) {
        tp.setStyle(Paint.Style.STROKE);
        tp.setStrokeWidth(mStrokeWidth);
        tp.setColor(mStrokeColor);
    }
}

总结

总之,SpannableStringBuilder 是一种很方便的创建富文本的方式,可以让您在文本中添加各种样式和效果。

如果对你有所帮助的话,不妨 Star 或 Fork,青山不改,绿水长流 有缘江湖再见 ~

源码地址:RichTextDemo

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

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

相关文章

wandb快速上手、使用心得(超好用的Tensorboard高替品)

这里写目录标题 1 wandb介绍2 快速上手3 使用心得3.1 一张图展示两条线3.2 想要科学上网和wandb一起使用&#xff08;离线使用&#xff09;3.3 未完待续 1 wandb介绍 wandb地址&#xff1a;wandb Wandb&#xff08;Weights & Biases&#xff09;是一个用于机器学习实验跟踪…

智慧城市建设电气火灾智慧消防措施 安科瑞 许敏

1、引言 “经检测&#xff0c;发现管辖单位南通王子造纸企业二氧化氯装置发生二级警报&#xff0c;可能引发火灾&#xff0c;请立即出警。”日前&#xff0c;南通消防救援支队大数据平台DCS化工火源预警系统发出警报&#xff0c;大屏幕显示辖区企业南通王子造纸企业出现险情。D…

B站618“杀”疯了?UP主直播带货GMV连年破亿!

众多主流平台已经早早构建出较为完整的直播带货体系&#xff0c;而B站则是从去年双十一才宣布正式加入全平台直播带货&#xff0c;同时上线购物直播专区&#xff0c;到今年618年中购物大促&#xff0c;B站已经在大步向前摸索属于本平台的直播带货阵营。 一直以来B站带着二次元…

TC8:SOMEIPSRV_FORMAT_15-18

SOMEIPSRV_FORMAT_15: Instance ID field of the Type 1 Entry 目的 检查Type 1 Entry(Offer Service)的“Instance ID”字段 测试步骤 DUT CONFIGURE:启动具有下列信息的服务Service ID:SERVICE-ID-1Instance数量:1Tester:客户端-1发送SOME/IP Notification消息Entry T…

后端web开发之maven

这里写目录标题 介绍创建maven项目作用作用1作用2作用3 简介 依赖管理依赖配置依赖传递简介依赖传递的可视化快捷键 排除依赖依赖范围生命周期介绍执行流程 介绍 创建maven项目 注意 maven属于项目一级&#xff0c;所以在创建项目的时候 直接选择maven项目按照步骤创建即可&a…

Java Web基础面试题整理

1、什么是Servlet&#xff1f; 可以从两个方面去看Servlet&#xff1a; a、API&#xff1a;有一个接口servlet&#xff0c;它是servlet规范中定义的用来处理客户端请求的程序需要实现的顶级接口。 b、组件&#xff1a;服务器端用来处理客户端请求的组件&#xff0c;需要在we…

【2023,学点儿新Java-12】小结:阶段性复习 | Java学习书籍推荐(小白该读哪类Java书籍?有一定基础后,再去读哪类书籍?)

前情回顾&#xff1a; 【2023&#xff0c;学点儿新Java-11】基础案例练习&#xff1a;输出个人基础信息、输出心形 | Java中 制表符\t 和 换行符\n 的简单练习【2023&#xff0c;学点儿新Java-10】Java17 API文档简介&获取 |详解Java核心机制&#xff1a;JVM |详解Java内存…

【FPGA入门】第六篇、异步串口通信

目录 第一部分、相关知识 1、UART和RS232的区别 2、UART与USART的区别 3、全双工&#xff1f; 4、RS232通信协议 5、波特率 6、如何将外部异步信号变为内部同步信号&#xff1f; 7、什么时间点让FPGA去采集rx线上的数据&#xff1f; 第二部分、串口通信时序图 1、…

OWASP之SSRF服务器伪造请求

文章目录 一、SSRF定义二、形成原因1.提供请求功能2.地址没做限制 三、漏洞危害1.可以对服务器所在内网、本地进行端口扫描&#xff0c;获取一些服务的信息等2.目标网站本地敏感数据的读取3.内外网主机应用程序漏洞的利用4.内外网Web站点漏洞的利用 四、ssrf挖掘1.从WEB功能上寻…

SpringBoot相关知识

SpringBoot知识 1 SpringBoot 介绍及其使用原因 Spring Boot是一个用于创建独立的、基于Java的生产级别的应用程序的框架。它旨在简化Spring应用程序的开发过程&#xff0c;减少开发人员的配置工作&#xff0c;从而提高开发效率。 原因: (1) 简化开发&#xff1a;Spring Boot…

Hadoop(HA)

文章目录 1、HA 概述2、HDFS-HA 集群搭建3、HDFS-HA 核心问题4、HDFS-HA 手动模式4.1 环境准备4.2 规划集群4.3 配置 HDFS-HA 集群4.4 启动 HDFS-HA 集群 5、HDFS-HA 自动模式5.1 HDFS-HA 自动故障转移工作机制5.2 HDFS-HA 自动故障转移的集群规划5.3 配置 HDFS-HA 自动故障转移…

java企业工程项目管理系统平台源码

工程项目管理软件&#xff08;工程项目管理系统&#xff09;对建设工程项目管理组织建设、项目策划决策、规划设计、施工建设到竣工交付、总结评估、运维运营&#xff0c;全过程、全方位的对项目进行综合管理 工程项目各模块及其功能点清单 一、系统管理 1、数据字典&#…

基于pyqt5、mysql、yolov7、chatgpt的小麦病害检测系统的设计与实现(基础版)

基于pyqt5、mysql、yolov7、chatgpt的小麦病害检测系统设计与实现 一、界面设计1.1安装pyqt51.2创建用户子窗体1.3创建管理员主窗体1.4创建管理员子窗体1.5创建系统登陆界面 二、环境搭建2.1pyqt5工具配置2.2mysql5.7安装 三、编程实现3.1初始化数据库3.2创建用户数据库sdk文件…

从零构建后端项目-配置Shiro+JWT

目录 Shiro和JWT技术 一、Shiro简介 什么是认证&#xff1f; 什么是授权&#xff1f; Shiro靠什么做认证与授权的&#xff1f; 二、JWT简介 JWT可以用在单点登录的系统中 JWT兼容更多的客户端 创建JwtUtil工具类 一、导入依赖库 二、定义密钥和过期时间 三、创…

强大的Kotlin也能搞定,测试利器MockK你不能不知道

目录 前言&#xff1a; 为什么需要MockK 关键字 Mock Kotlin的类时报错 静态方法如何Mock Jmockit MockK使用示例 普通使用 mockkObject mockkStatic mock private method Context Mock 遇到的一些小坑 最后 前言&#xff1a; MockK是一个强大且易于使用的Kotli…

爆肝整理,手机App接口测试大全指南,看这篇就够了...

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 App和Web请求服务…

用prim和kruskal算法求最小生成树问题

最短网络 题目http://ybt.ssoier.cn:8088/problem_show.php?pid1350 #include<bits/stdc.h> using namespace std; const int N110; int w[N][N]; bool st[N]; int dist[N]; int n,res0; void prim() {memset(dist,0x3f,sizeof dist);dist[1]0;//初始化第一个点到自己…

优化回声消除过程:舒适噪声生成算法的应用与原理

在回声消除中&#xff0c;舒适噪声生成(Comfort Noise Generator&#xff0c;CNG)算法是一种常用的技术&#xff0c;它被用来减轻回声消除过程中产生的不适感和声音失真。舒适噪声生成算法通过添加特定的噪声信号来模拟人耳的听觉特性&#xff0c;以改善声音的自然度和舒适度。…

Cpp面试题:main函数执行以前,还会执行什么代码?

Cpp面试题:main函数执行以前&#xff0c;还会执行什么代码&#xff1f; 在 main() 函数执行之前和之后&#xff0c;C 程序可能会执行以下代码&#xff1a; 静态对象的构造函数&#xff1a;如果程序中有静态对象&#xff08;全局变量或静态成员变量&#xff09;&#xff0c;它们…

深入了解 vcruntime140 文件,从多方面解析vcruntime140

vcruntime140 是一个重要的文件&#xff0c;它在 Windows 系统中扮演着重要的角色。如果不小心缺失了&#xff0c;那么你的电脑就会出现问题&#xff0c;今天我们就来探讨一下vcruntime140这个文件&#xff0c;分别从背景和预防丢失&#xff0c;到如何修复丢失vcruntime140来给…