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拼凑起来就想打自己脸。。。
还有很多属性可以设置,这里就不详细说了,我常用的就这么几个。
讲解完毕,( ^_^ )/~~拜拜