原文: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:

  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控件:

  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来做下演示

  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)

  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)

  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)

  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)

  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)

  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)

  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

  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 谢谢!

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

  1. Android项目实战--手机卫士开发系列教程

    <ignore_js_op> banner131010.jpg (71.4 KB, 下载次数: 0) 下载附件  保存到相册 2 分钟前 上传   Android项目实战--手机卫士01- ...

  2. Android项目实战(二十九):酒店预定日期选择

    先看需求效果图: 几个需求点: 1.显示当月以及下个月的日历 (可自行拓展更多月份) 2.首次点击选择"开始日期",再次点击选择"结束日期" (1).如果&qu ...

  3. Android项目实战(四十九):Andoird 7.0+相机适配

    解决方案类似: Android项目实战(四十):Andoird 7.0+ 安装APK适配 解决方法: 一.在AndroidManifest.xml 文件中添加 四大组件之一的 <provider ...

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

    前言: 项目中多处用到对话框,用系统对话框太难看,就自己写一个自定义对话框. 对话框包括:1.圆角 2.app图标 , 提示文本,关闭对话框的"确定"按钮 难点:1.对话框边框圆角 ...

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

    Android项目实战(三十二):圆角对话框Dialog   前言: 项目中多处用到对话框,用系统对话框太难看,就自己写一个自定义对话框. 对话框包括:1.圆角 2.app图标 , 提示文本,关闭对话 ...

  6. (转载)Android项目实战(二十七):数据交互(信息编辑)填写总结

    Android项目实战(二十七):数据交互(信息编辑)填写总结   前言: 项目中必定用到的数据填写需求.比如修改用户名的文字编辑对话框,修改生日的日期选择对话框等等.现总结一下,方便以后使用. 注: ...

  7. (转载)Android项目实战(二十八):Zxing二维码实现及优化

    Android项目实战(二十八):Zxing二维码实现及优化   前言: 多年之前接触过zxing实现二维码,没想到今日项目中再此使用竟然使用的还是zxing,百度之,竟是如此牛的玩意. 当然,项目中 ...

  8. (转载)Android项目实战(十七):QQ空间实现(二)—— 分享功能 / 弹出PopupWindow

    Android项目实战(十七):QQ空间实现(二)—— 分享功能 / 弹出PopupWindow   这是一张QQ空间说说详情的截图. 分析: 1.点击右上角三个点的图标,在界面底部弹出一个区域,这个 ...

  9. (转载)Android项目实战(二十八):使用Zxing实现二维码及优化实例

    Android项目实战(二十八):使用Zxing实现二维码及优化实例 作者:听着music睡 字体:[增加 减小] 类型:转载 时间:2016-11-21我要评论 这篇文章主要介绍了Android项目 ...

随机推荐

  1. svn pre commit

    windows下的必须要用.bat文件,pre-commit.bat ================================================== @echo off set ...

  2. 利用huson的日志获取编译错误信息的做法

    作者:朱金灿 来源:http://blog.csdn.net/clever101 使用hudson编译一百多个VC工程,输出的日志有6M之大,摆在我面前的一个问题是如何利用这个日志信息来获取编译错误信 ...

  3. JVM源码系列:ThreadMXBean 打出堆栈信息原理分析

    我们通常会使用工具jstack 去跟踪线程信息,其如何实现使用attach 的方式还是ptrace 的方式,这些可以去参考本人的博客的其他文章. 但这些方式都是外部使用的方式,如何直接使用java代码 ...

  4. 1069. The Black Hole of Numbers (20)【模拟】——PAT (Advanced Level) Practise

    题目信息 1069. The Black Hole of Numbers (20) 时间限制100 ms 内存限制65536 kB 代码长度限制16000 B For any 4-digit inte ...

  5. 前端切图:手机端自适应布局demo

    手机端自适应布局demo原型如下: 图片发自简书App 要求如下:适应各种机型源码如下: <!DOCTYPE html > <html> <head> <me ...

  6. AnimatorSet和PropertyValuesHolders.ofKeyframe

    如果要多个动画配合工作,需要把他们放入AnimatorSet中 ObjectAnimator animator1 = ObjectAnimator.ofFloat(...); animator1.se ...

  7. 使用相对路径导入ado库的方法

    作者:朱金灿 来源:http://blog.csdn.net/clever101 常用的导入ado库的语句: #import "c:\program files\common files\s ...

  8. js typeof instanceof

    一般都是用typeof推断变量存在 例如if(typeof a!="undefined"){}.不是要去使用if(a)因为假定a不存在(未申报)将是错误的. 由于typeof经验n ...

  9. Android, iOS, 各种软件汇总

    Android: 长截图:软件叫PPIICC的可以截图之后拼接:有些手机自带截图,比如小米,华为,三星等. 视频:全格式的Kodi XBMC, 一般的:moboplayer, VLC, F蔷:***, ...

  10. c语言学习笔记(6)——for和while循环

    for和while等价替换 -------------------------- int i = 1; for (i; i<=100; i++){ sum = sum + 1; } ------ ...