当前位置:首页 > Android > 正文内容

SpannableString与SpannableStringBuilder

jsc9年前 (2016-04-07)Android3446

一、概述


1、SpannableStringSpannableStringBuilder与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("博客");

20140901205141739.png

(转自博客:《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控件:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"  
    xmlns:tools="http://schemas.android.com/tools"  
    android:layout_width="match_parent"  
    android:layout_height="match_parent"  
    tools:context="com.example.try_spannable_blog.MainActivity" >  
  
    <EditText  
        android:id="@+id/edit"  
        android:layout_width="wrap_content"  
        android:layout_height="wrap_content" />  
  
</RelativeLayout>

(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);  
    }  
}

初始化效果是这样的:

20140902102601875.png

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

20140902103003543.png

在前面和后面都加入虾米两个字,可见,前面的虾米没有任何效果,后面的则不同,添加上相同的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);

效果:

20140902110520872.png

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);

是是是.png

3、字体大小(AbsoluteSizeSpan)

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

擦擦擦.png

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);

少吵吵.png

5、删除线(StrikethroughSpan)

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

费.png

6、下划线(UnderlineSpan)

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

改改.png

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);

反反复复.png

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


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


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


扫描二维码推送至手机访问。

版权声明:本文由微小站发布,如需转载请注明出处。

本文链接:https://jsc0.com/post/92.html

分享给朋友:

“ SpannableString与SpannableStringBuilder ” 的相关文章

使用自定义RadioButton和ViewPager实现TabHost效果和带滑动的页卡效果。

使用自定义RadioButton和ViewPager实现TabHost效果和带滑动的页卡效果。

在工作中又很多需求都不是android系统自带的控件可以达到效果的,内置的TabHost就是,只能达到简单的效果 ,所以这个时候就要自定义控件来达到效果:这个效果就是: 使用自定义RadioButton和ViewPager实现TabHost带滑动的页卡效果。    &...

Android权限问题整理

Android权限系统非常庞大,我们在Android系统中做任何操作都需要首先获取Android系统权限,本文记录了所有的Android权限问题,整理一下分享给大家。访问登记属性 android.permission.ACCESS_CHECKIN_PROPERTIES读取或写入登记check-in数...

google Zxing实现二维码、条形码扫描,仿微信二维码扫描效果

google Zxing实现二维码、条形码扫描,仿微信二维码扫描效果

    了解二维码这个东西还是从微信中,当时微信推出二维码扫描功能,自己感觉挺新颖的,从一张图片中扫一下竟然能直接加好友,不可思议啊,那时候还不了解二维码,呵呵,然后做项目的时候,老板说要加上二维码扫描功能,然后自己的屁颠屁颠的去百度,google...

实现应用程序只有在第一次启动时显示引导界面

第一次安装启动:启动页--->导航页-->主页面之后启动:启动页-->主页面实现的原理就是:在启动页面用做一个文件保存的状态,保存程序是不是第一次启动的状态。因为只是要保存一个状态,我们将这个程序是第一次打开就将他设为true,当他进入 主页面之后将他的状态未为false,因为都...

android上传图片至服务器

本实例实现了android上传手机图片至服务器,服务器进行保存服务器servlet代码publicvoid doPost(HttpServletRequest request, HttpServletResponse response)  ...

Android应用加入微信分享

Android应用加入微信分享

一、申请你的AppIDhttp://open.weixin.qq.com/  友情提示:推荐使用eclipse打包软件最后一步的MD5值去申请AppID二、官网下载libammsdk.jar包http://open.weixin.qq.com/download/?lang=zh_...