Android项目实战(一): SpannableString与SpannableStringBuilder

原文:Android项目实战(一): SpannableString与SpannableStringBuilder

前言:

曾经在一些APP中的一些类似“帮助”“关于”的界面看过一行文字显示不同的颜色的效果,如下效果:

本软件是一款高、大、上的社区类软件。

一般来说,这应该是由一个TextView来显示的,但是自己又不会实现,怎么办呢,只能一个颜色搞一个TextView连起来,形成上面的效果。

但是那样实现的话都显得太低级了。直到我偶然的知道了SpannableString 类。网上学习了一下,挺简单的一个类,网上详细的介绍很多,自己就不再测试写博了,直接转一个写的不错的留着以后项目中用吧。

本文转自:

http://blog.csdn.net/harvic880925/article/details/38984705 

一、概述

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:

[java] view plaincopy

  1. //使用SpannableString,必须一次传入,构造完成
  2. SpannableString word = new SpannableString("欢迎光临Harvic的博客");
  3. //使用SpannableStringBuilder,可以使用append()再添加
  4. SpannableStringBuilder multiWord = new SpannableStringBuilder();
  5. multiWord.append("欢迎光临");
  6. multiWord.append("Harvic的");
  7. 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控件:

[html] view plaincopy

  1. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
  2. xmlns:tools="http://schemas.android.com/tools"
  3. android:layout_width="match_parent"
  4. android:layout_height="match_parent"
  5. tools:context="com.example.try_spannable_blog.MainActivity" >
  6. <EditText
  7. android:id="@+id/edit"
  8. android:layout_width="wrap_content"
  9. android:layout_height="wrap_content" />
  10. </RelativeLayout>

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

[java] view plaincopy

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

初始化效果是这样的:

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

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

二、各种Span设置

在前面的一个小示例,大家应该也可以看出,要应用一个Span总共分三步:
1、构造String
2、构造Span
3、利用SetSpan()对指定范围的String应用这个Span

1、字体颜色设置(ForegroundColorSpan)

[java] view plaincopy

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

效果:

2、字体背景颜色(BackgroundColorSpan)

[java] view plaincopy

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

3、字体大小(AbsoluteSizeSpan)

[java] view plaincopy

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

4、粗体、斜体(StyleSpan)

[java] view plaincopy

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

5、删除线(StrikethroughSpan)

[java] view plaincopy

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

6、下划线(UnderlineSpan)

[java] view plaincopy

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

7、图片置换(ImageSpan)

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

[java] view plaincopy

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


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

本篇文章所涉及到图片及工程下载地址:http://download.csdn.net/detail/harvic880925/7854761

 

请大家尊重原创者版权,转载请标明出处:http://blog.csdn.net/harvic880925/article/details/38984705 谢谢!

原文地址:https://www.cnblogs.com/lonelyxmas/p/8970164.html

时间: 2024-10-03 06:01:55

Android项目实战(一): SpannableString与SpannableStringBuilder的相关文章

Android项目实战(十四):TextView显示html样式的文字

原文:Android项目实战(十四):TextView显示html样式的文字 项目需求: TextView显示一段文字,格式为:白雪公主(姓名,字数不确定)向您发来了2(消息个数,不确定)条消息 这段文字中名字和数字的长度是不确定的,还要求名字和数字各自有各自的颜色. 一开始我想的是用(转) SpannableString与SpannableStringBuilder来实现,因为它可以实现一段文字显示不同的颜色 但是貌似它只能固定哪些位置的文字显示什么样式,于是乎放弃. 然后就想到了用 Html

Android项目实战(十六):QQ空间实现(一)—— 展示说说中的评论内容并有相应点击事件

原文:Android项目实战(十六):QQ空间实现(一)-- 展示说说中的评论内容并有相应点击事件 大家都玩QQ空间客户端,对于每一个说说,我们都可以评论,那么,对于某一条评论: 白雪公主 回复 小矮人 : 你们好啊~ 我们来分析一下: 1.QQ空间允许我们 点击 回复人和被回复人的名字就可以进入对于用户的个人主页(即点击文字“白雪公主”/“小矮人”,就可以进入到这俩用户相应个人主页) 2.点击 回复的文字,就可以对回复人进行回复(即点击评论中回复的内容“你们好啊~”,便对弹出一个编辑框对回复人

android项目实战-背呗单词00-文章目录

一.准备篇android项目实战-背呗单词00-文章目录android项目实战-背呗单词01-软件说明android项目实战-背呗单词02-项目概述android项目实战-背呗单词03-项目图表android项目实战-背呗单词04-项目数据库说明 二.重要技术实现说明android项目实战-背呗单词DEV00-程序环境构架搭建android项目实战-背呗单词DEV01-拷贝单词书实现android项目实战-背呗单词DEV02-创建计划实现android项目实战-背呗单词DEV03-创建任务实现a

(转载)Android项目实战(三十二):圆角对话框Dialog

Android项目实战(三十二):圆角对话框Dialog 前言: 项目中多处用到对话框,用系统对话框太难看,就自己写一个自定义对话框. 对话框包括:1.圆角 2.app图标 , 提示文本,关闭对话框的"确定"按钮 难点:1.对话框边框圆角显示 2.考虑到提示文本字数不确定,在不影响美观的情况下,需要在一行内显示提示的文字信息   3.设置对话框的宽和高 技术储备: 1.安卓开发_使用AlertDialog实现对话框    知道AlertDialog有setView(view) ,Dia

android项目实战-背呗单词DEV07-单词测试实现

该篇说明 该篇我们进行单词测试实现讲解 也就是单词测试界面WordExamActivity中功能 布局也需要在xml中实现 但是也需要有单词测试视图类来设置一些值具体查看对照源码 在该界面中,测试完后会更新数据 效果如图 流程图 单词测试界面功能流程详解 1> 显示单词测试信息 a> 首先要加载单词测试数据 需要调用单词测试管理模块加载数据功能 private void loadWordExamData() { loadingExamDataProgressBar = (ProgressBar

Android项目实战(八):列表右侧边栏拼音展示效果

原文:Android项目实战(八):列表右侧边栏拼音展示效果 之前忙着做项目,好久之前的技术都没有时间总结,而发现自己的博客好多写的技术都比自己掌握的时候晚了很多.不管怎么样,写技术博客一定是一个想成为优秀程序猿或者已经是优秀程序猿必须做的.好吧,下面进行学习阶段. 记得很久之前就使用过侧边拼音栏了,先看下它的效果,一个列表,列表的右侧有一个拼音列表,当列表发生滑动的时候,拼音列表也随着滑动,而规律就是拼音列表滑动的位置为显示列表的当前位置的文字的首字母决定,当然,直接点击拼音列表的一个位置,显

Android项目实战(十二):解决OOM的一种偷懒又有效的办法

原文:Android项目实战(十二):解决OOM的一种偷懒又有效的办法 在程序的manifest文件的application节点加入android:largeHeap=“true” 即可. 对,只需要一句话! 那么这行代码的意思是什么呢? 简单的说就是使该APP获取最大可分配的内存,以便解决OOM问题. 但是.OOM问题出现的原因总得来说有两点: 1.某个手机的内存真的很少 2.代码问题,比如没有处理好Bitmap图片的大小 可以说,出现OOM的情况基本都是第二种情况,那么就需要修改代码,看看哪

Android项目实战(四):ViewPager切换动画(3.0版本以上有效果)

原文:Android项目实战(四):ViewPager切换动画(3.0版本以上有效果) 学习内容来自“慕课网” 一般APP进去之后都会有几张图片来导航,这里就学习怎么在这张图片切换的时候添加切换动画效果 先看布局文件 activity_main.layout <?xml version="1.0" encoding="utf-8"?> <FrameLayout xmlns:android="http://schemas.android.c

Android项目实战(三):实现第一次进入软件的引导页

原文:Android项目实战(三):实现第一次进入软件的引导页 最近做的APP接近尾声了,就是些优化工作了, 我们都知道现在的APP都会有引导页,就是安装之后第一次打开才显示的引导页面(介绍这个软件的几张可以切换的图) 自己做了一下,结合之前学过的 慕课网_ViewPager切换动画(3.0版本以上有效果) 思路很简单,APP的主界面还是作为主Activity,只要新添加一个类来判断是不是第一次打开APP 设主activity 名字为:MainActivity.java   判断是不是第一次打开