您的位置:首页 > 产品设计 > UI/UE

【Android进阶】SpannableString与SpannableStringBuilder使用

2016-06-20 00:25 519 查看
原文地址:http://blog.it985.com/14433.html

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;





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 :前后都包括。

下面写了个小demo,先看一下效果图:





代码如下所示:

提取出来的方法:

package com.example.richtextdemo;

import android.os.Bundle;
import android.R.drawable;
import android.app.Activity;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.text.Html;
import android.text.SpannableString;
import android.text.Spanned;
import android.text.TextPaint;
import android.text.method.LinkMovementMethod;
import android.text.style.ClickableSpan;
import android.text.style.ForegroundColorSpan;
import android.text.style.ImageSpan;
import android.text.style.URLSpan;
import android.view.Gravity;
import android.view.Menu;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;

public class MainActivity extends Activity {
private TextView text1,text2,text3,text4;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
text1 = (TextView) findViewById(R.id.text1);
text2 = (TextView) findViewById(R.id.text2);
text3 = (TextView) findViewById(R.id.text3);
text4 = (TextView) findViewById(R.id.text4);

//1.让文本和图片一起显示
text1.setText(showTextWithImage("我是文本[大兵]", R.drawable.ic_launcher));

//2.让某段文字变色
text2.setText(showTextWithColor("王二,小明,大兵等觉得很赞",Color.BLUE));

//3.让某段文字可以被点击并跳转超链接
String text = "详情请点击<a href='http://www.baidu.com'>百度</a>";
Spanned spanned = Html.fromHtml(text);
text3.setText(spanned);
text3.setMovementMethod(LinkMovementMethod.getInstance());//设置可以点击超链接

//3.让某段文字可以被点击并自定义点击的逻辑操作
String string = "王二,小明,大兵等觉得很赞";
SpannableString ss= new SpannableString(string);
MyUrlSpan urlSpan= new MyUrlSpan(string.substring(0, string.indexOf(",")));
ss.setSpan(urlSpan, 0, 2, SpannableString.SPAN_INCLUSIVE_EXCLUSIVE);
text4.setText(ss);
text4.setMovementMethod(LinkMovementMethod.getInstance());

}

/**
* 让某几个文字显示颜色
* @param string
* @param color
* @return
*/
private CharSequence showTextWithColor(String string,int color) {
SpannableString ss = new SpannableString(string);
ForegroundColorSpan colorSpan = new ForegroundColorSpan(color);
int end = string.indexOf("等");
ss.setSpan(colorSpan, 0, end, SpannableString.SPAN_INCLUSIVE_EXCLUSIVE);
return ss;
}

/**
* 让图片和文字一起显示
* @param text
* @param imageRes
* @return
*/
private SpannableString showTextWithImage(String text,int imageRes){
SpannableString ss = new SpannableString(text);
Drawable drawable = getResources().getDrawable(imageRes);

//设置边界
//		drawable.setBounds(0,0,drawable.getIntrinsicWidth(),drawable.getIntrinsicHeight());
drawable.setBounds(0,0,20,20);
ImageSpan span = new ImageSpan(drawable);

int start = text.indexOf("[");
int end = text.indexOf("]")+1;
ss.setSpan(span, start,end,SpannableString.SPAN_INCLUSIVE_EXCLUSIVE);

return ss;
}

class MyUrlSpan extends URLSpan{
public MyUrlSpan(String url) {
super(url);
}
@Override
public void onClick(View widget) {
Toast.makeText(MainActivity.this, getURL(), 0).show();
widget.clearFocus();
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: