您的位置:首页 > 移动开发 > Android开发

使用SpannableString设置部分文字大小、颜色、超链接、点击事件

2015-08-09 12:27 756 查看
Android中需要给TextView中的个别字设置为超链接,或者设置个别字的颜色、字体等,需要用到Spannable对象。

效果如下:



baidu和youku字段做了autolink,设置字体大小和颜色,youku并取消了下划线。

private void initView() {
TextView textView = (TextView) findViewById(R.id.tv_content);
String content = textView.getText().toString();
// This is a test,you can click baidu or youku.
SpannableString ss = new SpannableString(content);
// flag:标识在 Span 范围内的文本前后输入新的字符时是否把它们也应用这个效果
//  Spanned.SPAN_EXCLUSIVE_EXCLUSIVE(前后都不包括)、
//  Spanned.SPAN_INCLUSIVE_EXCLUSIVE(前面包括,后面不包括)、
// Spanned.SPAN_EXCLUSIVE_INCLUSIVE(前面不包括,后面包括)、
// Spanned.SPAN_INCLUSIVE_INCLUSIVE(前后都包括)
// 设置网络超链接
ss.setSpan(new URLSpan("http://www.baidu.com"), content.indexOf("baidu"), content.indexOf(" or"), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
ss.setSpan(new URLSpan("http://www.youku.com"), content.indexOf("youku"), ss.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
// 设置字体颜色
ss.setSpan(new ForegroundColorSpan(Color.parseColor("#ff0000")), content.indexOf("baidu"), content.indexOf(" or"), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
ss.setSpan(new ForegroundColorSpan(Color.parseColor("#ff00ff")), content.indexOf("youku"), ss.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
// 设置字体大小
ss.setSpan(new AbsoluteSizeSpan(sp2px(this, 25)), content.indexOf("baidu"), content.indexOf(" or"), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
ss.setSpan(new AbsoluteSizeSpan(sp2px(this, 30)), content.indexOf("youku"), ss.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
// 取消下划线
ss.setSpan(new MyUnderlineSpan(), content.indexOf("youku"), ss.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);

textView.setText(ss);
textView.setMovementMethod(LinkMovementMethod.getInstance());
}

// 通过继承UnderlineSpan重写updateDrawState方法setUnderlineText(false)取消下划线
class MyUnderlineSpan extends  UnderlineSpan{

@Override
public void updateDrawState(TextPaint ds) {
ds.setUnderlineText(false);
}
}

private int sp2px(Context context, float spValue) {
final float fontScale = context.getResources().getDisplayMetrics().scaledDensity;
return (int) (spValue * fontScale + 0.5f);
}


UnderLineSpan源码很简单,在updateDrawState设置下划线

public class UnderlineSpan extends CharacterStyle
implements UpdateAppearance, ParcelableSpan {
public UnderlineSpan() {
}

public UnderlineSpan(Parcel src) {
}

public int getSpanTypeId() {
return TextUtils.UNDERLINE_SPAN;
}

public int describeContents() {
return 0;
}

public void writeToParcel(Parcel dest, int flags) {
}

@Override
public void updateDrawState(TextPaint ds) {
ds.setUnderlineText(true);
}
}


因此只要继承UnderlineSpan重写下updateDrawState方法即可去掉下划线

class MyUnderlineSpan extends  UnderlineSpan{

@Override
public void updateDrawState(TextPaint ds) {
ds.setUnderlineText(false);
}
}


ClickableSpan源码的话可看到 updateDrawState默认设置带有下划线

public abstract class ClickableSpan extends CharacterStyle implements UpdateAppearance {

/**
* Performs the click action associated with this span.
*/
public abstract void onClick(View widget);

/**
* Makes the text underlined and in the link color.
*/
@Override
public void updateDrawState(TextPaint ds) {
ds.setColor(ds.linkColor);
ds.setUnderlineText(true);
}
}


URLSpan 源码继承于ClickableSpan 并在onClick发起一个意图调用浏览器进行网址的浏览,由于继承于ClickableSpan所以默认带下划线

public class URLSpan extends ClickableSpan implements ParcelableSpan {

private final String mURL;

public URLSpan(String url) {
mURL = url;
}

public URLSpan(Parcel src) {
mURL = src.readString();
}

public int getSpanTypeId() {
return TextUtils.URL_SPAN;
}

public int describeContents() {
return 0;
}

public void writeToParcel(Parcel dest, int flags) {
dest.writeString(mURL);
}

public String getURL() {
return mURL;
}

@Override
public void onClick(View widget) {
Uri uri = Uri.parse(getURL());
Context context = widget.getContext();
Intent intent = new Intent(Intent.ACTION_VIEW, uri);
intent.putExtra(Browser.EXTRA_APPLICATION_ID, context.getPackageName());
context.startActivity(intent);
}
}


我们想自己定义webview加载内容的话可以继承URLSpan 进行处理

class MyURLSpan extends URLSpan {
@Override
public void onClick(View widget) {
Uri uri = Uri.parse(getURL());
// 这里拿到uri进行自己的加载操作即可
dosomething();
}
}


可以看到Spannable是个相当实用的类,想起以前用textview大小颜色或要分开做点击处理的时候,用几个textview拼凑起来就想打自己脸。。。

还有很多属性可以设置,这里就不详细说了,我常用的就这么几个。

讲解完毕,( ^_^ )/~~拜拜
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  android 字体 textview