热门标签 | HotTags
当前位置:  开发笔记 > 前端 > 正文

Android中的SpannableString与SpannableStringBuilder详解

这篇文章主要给大家介绍了关于Android中SpannableString与SpannableStringBuilder的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧。

前言

最近在学习Android开发,发现确实有太多东西需要去整理,去学习。慢慢来吧,任何东东的深入学习都是不简单的。今天稍微整理下SpannableString与SpannableStringBuilder,因为在上篇中,我们曾讲到过有关CharSequence的东东,有关CharSequence的话,这两个类是必谈的,所以这里加以整理。

一、概述

1、SpannableString、SpannableStringBuilder与String的关系

首先SpannableString、SpannableStringBuilder基本上与String差不多,也是用来存储字符串,但它们俩的特殊就在于有一个SetSpan()函数,能给这些存储的String添加各种格式或者称样式(Span),将原来的String以不同的样式显示出来,比如在原来String上加下划线、加背景色、改变字体颜色、用图片把指定的文字给替换掉,等等。所以,总而言之,SpannableString、SpannableStringBuilder与String一样, 首先也是传字符串,但SpannableString、SpannableStringBuilder可以对这些字符串添加额外的样式信息,但String则不行。

注意:如果这些额外信息能被所用的方式支持,比如将SpannableString传给TextView;也有对这些额外信息不支持的,比如前一章讲到的Canvas绘制文字,对于不支持的情况,SpannableString和SpannableStringBuilder就是退化为String类型,直接显示原来的String字符串,而不会再显示这些附加的额外信息。

2、SpannableString与SpannableStringBuilder区别

它们的区别在于 SpannableString像一个String一样,构造对象的时候传入一个String,之后再无法更改String的内容,也无法拼接多个 SpannableString;而SpannableStringBuilder则更像是StringBuilder,它可以通过其append()方法来拼接多个String:

//使用SpannableString,必须一次传入,构造完成 
SpannableString word = new SpannableString("欢迎光临Harvic的博客"); 
 
//使用SpannableStringBuilder,可以使用append()再添加 
SpannableStringBuilder multiWord = new SpannableStringBuilder(); 
multiWord.append("欢迎光临"); 
multiWord.append("Harvic的"); 
multiWord.append("博客"); 


(转自博客:《android - SpannableString或SpannableStringBuilder以及string.xml文件中的整型和string型代替》)

因为Spannable等最终都实现了CharSequence接口,所以可以直接把SpannableString和SpannableStringBuilder通过TextView.setText()设置给TextView。

3、SetSpan()

void setSpan (Object what, int start, int end, int flags)

函数意义:给SpannableString或SpannableStringBuilder特定范围的字符串设定Span样式,可以设置多个(比如同时加上下划线和删除线等),Falg参数标识了当在所标记范围前和标记范围后紧贴着插入新字符时的动作,即是否对新插入的字符应用同样的样式。(这个后面会具体举例说明)

参数说明:

  • object what :对应的各种Span,后面会提到;
  • int start:开始应用指定Span的位置,索引从0开始
  • int end:结束应用指定Span的位置,特效并不包括这个位置。比如如果这里数为3(即第4个字符),第4个字符不会有任何特效。从下面的例子也可以看出来。

int flags:取值有如下四个

  • Spannable.SPAN_EXCLUSIVE_EXCLUSIVE:前后都不包括,即在指定范围的前面和后面插入新字符都不会应用新样式 
  • Spannable.SPAN_EXCLUSIVE_INCLUSIVE:前面不包括,后面包括。即仅在范围字符的后面插入新字符时会应用新样式
  • Spannable.SPAN_INCLUSIVE_EXCLUSIVE:前面包括,后面不包括。
  • Spannable.SPAN_INCLUSIVE_INCLUSIVE:前后都包括。

举个例子来说明这个前后包括的问题:

由于Flag的作用是用来指定范围前后输入新的字符时,会不会应用效果的,所以我们利用EditText来显示SpannableString

(1)、布局XML中加入一个EditText控件:

 
 
  
 
 

(2)、这里用一个改变字体颜色的Span来做下演示

public class MainActivity extends Activity { 
 
 private EditText editText; 
 @Override 
 protected void onCreate(Bundle savedInstanceState) { 
 super.onCreate(savedInstanceState); 
 setContentView(R.layout.activity_main); 
 
 editText = (EditText)findViewById(R.id.edit); 
 
 //改变字体颜色 
 //先构造SpannableString 
 SpannableString spanString = new SpannableString("欢迎光临Harvic的博客"); 
 //再构造一个改变字体颜色的Span 
 ForegroundColorSpan span = new ForegroundColorSpan(Color.BLUE); 
 //将这个Span应用于指定范围的字体 
 spanString.setSpan(span, 1, 3, Spannable.SPAN_EXCLUSIVE_INCLUSIVE); 
 //设置给EditText显示出来 
 editText.setText(spanString); 
 } 
} 

初始化效果是这样的:


分别在设置Span的前面和后面加入新文字,结果是这样的


在前面和后面都加入虾米两个字,可见,前面的虾米没有任何效果,后面的则不同,添加上相同的Span特效,这是由于我们设置了Spannable.SPAN_EXCLUSIVE_INCLUSIVE的原因,即(前面不应用特效,后面应用特效),其它几个Flags参数的含义想必大家也都清楚了。在此就不再赘述。

二、各种Span设置

在前面的一个小示例,大家应该也可以看出,要应用一个Span总共分三步:

      1、构造String

      2、构造Span
      3、利用SetSpan()对指定范围的String应用这个Span

1、字体颜色设置(ForegroundColorSpan)

SpannableString spanString = new SpannableString("欢迎光临Harvic的博客"); 
//再构造一个改变字体颜色的Span 
ForegroundColorSpan span = new ForegroundColorSpan(Color.BLUE); 
//将这个Span应用于指定范围的字体 
spanString.setSpan(span, 1, 5, Spannable.SPAN_EXCLUSIVE_INCLUSIVE); 
//设置给EditText显示出来 
editText.setText(spanString); 

效果:


2、字体背景颜色(BackgroundColorSpan)

SpannableString spanString = new SpannableString("欢迎光临Harvic的博客"); 
BackgroundColorSpan span = new BackgroundColorSpan(Color.YELLOW); 
spanString.setSpan(span, 0, 3, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); 
editText.setText(spanString); 


3、字体大小(AbsoluteSizeSpan)

SpannableString spanString = new SpannableString("欢迎光临Harvic的博客"); 
AbsoluteSizeSpan span = new AbsoluteSizeSpan(16); 
spanString.setSpan(span, 2, 5, Spannable.SPAN_INCLUSIVE_INCLUSIVE); 
editText.setText(spanString); 


4、粗体、斜体(StyleSpan)

SpannableString spanString = new SpannableString("欢迎光临Harvic的博客"); 
StyleSpan span = new StyleSpan(Typeface.BOLD_ITALIC); 
spanString.setSpan(span, 1, 4, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); 
editText.setText(spanString); 


5、删除线(StrikethroughSpan)

SpannableString spanString = new SpannableString("欢迎光临Harvic的博客"); 
StrikethroughSpan span = new StrikethroughSpan(); 
spanString.setSpan(span, 2, 5, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); 
editText.setText(spanString); 


6、下划线(UnderlineSpan)

SpannableString spanString = new SpannableString("欢迎光临Harvic的博客"); 
UnderlineSpan span = new UnderlineSpan(); 
spanString.setSpan(span, 1, 4, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); 
editText.setText(spanString); 


7、图片置换(ImageSpan)

ImagSpan有很多构造函数,一般是通过传入Drawableg来构造,详细的构造说明看这里http://developer.android.com/reference/android/text/style/ImageSpan.html

SpannableString spanString = new SpannableString("欢迎光临Harvic的博客"); 
Drawable d = getResources().getDrawable(R.drawable.ic_launcher); 
d.setBounds(0, 0, d.getIntrinsicWidth(), d.getIntrinsicHeight()); 
ImageSpan span = new ImageSpan(d, ImageSpan.ALIGN_BASELINE); 
spanString.setSpan(span, 2, 4, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); 
editText.setText(spanString); 


这个函数的不同之处在于,前几都是在原来文字的基础上加上特效,而这里却是利用图片将文字替换。如果遇到不支持显示图片的函数,比如前一篇中的canvas绘图。就会退化成String,即以原来的String字符串来显示。

本篇文章所涉及到图片及工程下载地址:http://xiazai.jb51.net/201710/yuanma/SpannableString_SpannableStringBuilder(jb51.net).rar

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对的支持。


推荐阅读
  • 深入理解Django中的AJAX应用
    本文详细介绍了AJAX技术及其在Django框架中的应用。AJAX,即异步JavaScript和XML,允许网页在不重新加载整个页面的情况下与服务器交换数据并更新部分网页。 ... [详细]
  • 本文详细介绍了ejabberd中的验证码服务、接收器以及服务器间通信的监督者和工作进程,包括它们的启动方式和主要功能。 ... [详细]
  • 利用Java与Tesseract-OCR实现数字识别
    本文深入探讨了如何利用Java语言结合Tesseract-OCR技术来实现图像中的数字识别功能,旨在为开发者提供详细的指导和实践案例。 ... [详细]
  • 深入探讨PHP中的输出缓冲技术(Output Buffering)
    本文深入解析了PHP中输出缓冲(Output Buffering)的原理及其在Web开发中的应用,特别是如何通过输出缓冲技术有效管理HTTP头部信息,提高代码的灵活性与健壮性。 ... [详细]
  • 深入理解Java NIO:基础概念与原理
    本文介绍了Java NIO(New Input/Output)的基本概念,包括同步与异步、阻塞与非阻塞等核心理念,以及NIO相对于传统IO的优势和应用场景。通过详细解析这些概念,帮助读者更好地理解和掌握NIO的使用。 ... [详细]
  • 本问题涉及对一个非负整数数组执行加一操作。数组以最高位数字在前的方式存储,每个数组元素仅包含一位数字。假设该整数没有前导零,除非该整数为0。 ... [详细]
  • 本文详细介绍了 Freemarker 模板引擎中的 include 指令,以及如何利用该指令从其他文件中引入内容,以增强页面的模块化和可维护性。 ... [详细]
  • 本文介绍了两种有效的方法来检查Android应用是否拥有特定权限,如媒体读写权限(media_rw)。通过这些方法,开发者和安全人员可以更好地了解应用的行为,确保其不会滥用权限。 ... [详细]
  • Struts2(六) 用Struts完成客户列表显示
    Struts完成客户列表显示所用的基础知识在之前的随笔中已经讲过。这篇是介绍如何使用Struts完成客户列表显示。下面是完成的代码执行逻辑图:抽取项目部分代码相信大家 ... [详细]
  • 本文详细介绍了DOM(文档对象模型)的基本概念、结构及操作方法。DOM作为一种API,允许开发者以编程方式访问HTML和XML文档的结构,实现页面内容的动态修改。 ... [详细]
  • 本周工作重点在于细化用户需求文档,同时深入学习了jQuery的操作技巧及其源码解析。通过阅读知乎上的高质量问答,获取了关于如何有效阅读和理解jQuery源码的专业建议。 ... [详细]
  • 本文详细介绍了printf函数中的常见格式化符号和转义字符,以及如何在实际编程中灵活运用这些符号进行格式化输出。 ... [详细]
  • 优化 DropDownList 与 TextBox 的交互体验
    本文介绍了一种解决方案,通过在 DropDownList 前添加一个 TextBox 来提升用户体验。当选项过多时,用户可以通过在 TextBox 中输入关键词来快速定位并选择相应的选项。 ... [详细]
  • 现代软件工程开发体验:结对编程
    距现代软件工程开课已经3周,按照课程安排,在最近的9天中,我们进行了极限编程模式的体验:pairwork(结对编程,具体见链接),对象是在academicsearchmap上添加一些新特性。经过选 ... [详细]
  • 本文探讨了如何在Android框架下通过自定义资源文件实现系统风格的统一,包括系统资源文件的位置、引用方法、系统主题的设置及修改等内容。 ... [详细]
author-avatar
蕊儿巧乐-滋
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有