我們用xml布局的時候,一個TextView通常只能擁有一個顯示樣式,如textSize,textColor等.當(dāng)需要想突出顯示TextView中的一些字符或文本的話,應(yīng)該怎么辦呢?
<h2>string.xml</h2>
在string.xml 中,我們可以對字符串做一些簡單的樣式更改,如下
將wall 的字體顏色置為紅色,大小置為50sp
<string name="color"> Humpty Dumpty sat on a <font fgcolor="-#10000" size='50'>wall</font></string>
tips:
- 紅色的顏色代碼為
#FFFFFFFF,但如果直接設(shè)為fgcolor="#ffff0000"則不能奏效,甚至?xí)?dǎo)致目標(biāo)文本消失. 這是由于顏色的16進制值導(dǎo)致的,簡單的方法就是取值為0x100000000 -0xffff0000= 0x10000再取反,就能成功設(shè)置為紅色. - size中的值單位為dp
<h2>Html.fromHtml()</h2>
較簡易的方法是用Html語法,再使用Html.fromHtml() 轉(zhuǎn)化為有樣式的字符串,如下
mTextView.setText(Html.fromHtml("<font color='#cc0029'>Some</font> radom Color"));
<h2>自定義Span</h2>
Spanned 是 CharSequence 的子類,這意味著它也可以在TextVIew中顯示,Android 中有各種類型的span
-
AbsoluteSizeSpan指定字體大小 -
BackgroundColorSpan指定文本背景色 -
BulletSpan在文本前顯示圓點 ,類似html中的<li>效果 -
DrawableMarginSpan,IconMarginSpan,ImageSpan文本中添加圖片 -
ForegroundColorSpan改變字體顏色 -
LeadingMarginSpan調(diào)整文本縮進 -
ScaleXSpan橫向縮放文本 -
StrikethroughSpan添加刪除線 -
StyleSpan添加 正常,粗體,斜體樣式 -
SubscriptSpan下標(biāo)樣式 -
SuperscriptSpan上標(biāo)樣式 -
TextAppearanceSpan按照資源中的樣式表R.style.my_style來為文本添加樣式 -
TypefaceSpan設(shè)置字體 -
UnderlineSpan下劃線樣式 -
URLSpan可點擊打開鏈接 -
ClickableSpan抽象類,可以自定義文本點擊方法
注意,設(shè)置span比較消耗資源,如果可以,在后臺線程中操作再設(shè)置到控件中.
構(gòu)建自定義span 主要用到的是SpannableString和SpannableStringBuilder這兩個類
一般用法就是 先創(chuàng)建所需的Span,再用setSpan() 方法來進行設(shè)置.
<h3>tips:</h3>
-
ClickableSpan點擊后會出現(xiàn)文本背景色發(fā)生變化的情況, 可以在onClick事件中設(shè)置控件重繪來解決,如下
public class LinkClickSpan extends ClickableSpan {
AffLinkModel mLinkModel;
public LinkClickSpan(AffLinkModel linkModel) {
mLinkModel = linkModel;
}
@Override
public void onClick(View widget) {
Logger.t("method").i("click");
AffLinkDialog.getInstance(mLinkModel).show(getChildFragmentManager(), null);
widget.invalidate();
}
}
- 如果想用正則表達(dá)式將一段文本中特定文本標(biāo)記或替換,可以使用這個類
Replacer,如下
/**
* 文本正則替換器
* 支持替換將包含"<...>","[...]"的文本,變?yōu)槿サ衾ㄌ?并修改顏色和字體大小
* Author: yanhao(amosbake@gmail.com)
* Date : 2016-01-14
* Time: 15:21
*/
public class Replacer {
private static final String TAG = "Replacer";
private final CharSequence mSource;//需要修改的文本
private final CharSequence mReplacement;//待替換的文本
private final Matcher mMatcher;//正則匹配器
private int mAppendPosition;//當(dāng)前builder所在位置
private final boolean mIsSpannable;//代替換的樣式字符串是否存在樣式
//將符合正則的文本替換為指定文本
public static CharSequence replace(CharSequence source,String regex, CharSequence replacement){
Pattern pattern=Pattern.compile(regex);
Matcher matcher=pattern.matcher(source);
return new Replacer(matcher,replacement,source).doReplace();
}
//將符合正則的文本替換為指定文本 并修改字體大小和字體顏色
public static CharSequence replaceWithColorAndSize(CharSequence source,String regex,int color,int sizeIndp){
Pattern pattern=Pattern.compile(regex);
Matcher matcher=pattern.matcher(source);
return new Replacer(matcher,null,source).doOriginReplace(color,sizeIndp);
}
public Replacer(Matcher matcher, CharSequence replacement, CharSequence source) {
mMatcher = matcher;
mReplacement = replacement;
mSource = source;
mAppendPosition = 0;
mIsSpannable = replacement instanceof Spannable;
}
//執(zhí)行簡單替換的功能
private CharSequence doReplace() {
SpannableStringBuilder builder = new SpannableStringBuilder();
while (mMatcher.find()) {
appendRelacement(builder);
}
return appendTail(builder);
}
//執(zhí)行替換原文本,并指定替換的字體大小和顏色
private CharSequence doOriginReplace(int color,int textSize){
SpannableStringBuilder builder = new SpannableStringBuilder();
while (mMatcher.find()) {
try {
CharSequence charSource = mSource.subSequence(mMatcher.start()+1, mMatcher.end()-1);
//更換字體顏色
ForegroundColorSpan colorSpan=new ForegroundColorSpan(color);
//更換字體大小
AbsoluteSizeSpan sizeSpan=new AbsoluteSizeSpan(textSize,false);
SpannableStringBuilder stringBuilder=new SpannableStringBuilder(charSource);
stringBuilder.setSpan(colorSpan, 0, charSource.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
stringBuilder.setSpan(sizeSpan, 0, charSource.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
appendRelacement(builder, stringBuilder);
} finally {
continue;
}
}
return appendTail(builder);
}
private void appendRelacement(SpannableStringBuilder builder) {
builder.append(mSource.subSequence(mAppendPosition, mMatcher.start()));
CharSequence replacement = mIsSpannable
? copyCharSequenceWithSpans(mReplacement)
: mReplacement;
builder.append(replacement);
mAppendPosition = mMatcher.end();
}
private void appendRelacement(SpannableStringBuilder builder,CharSequence tempReplace) {
builder.append(mSource.subSequence(mAppendPosition, mMatcher.start()));
builder.append(tempReplace);
mAppendPosition = mMatcher.end();
}
private CharSequence copyCharSequenceWithSpans(CharSequence string) {
Parcel parcel = Parcel.obtain();
try {
TextUtils.writeToParcel(string, parcel, 0);
parcel.setDataPosition(0);
return TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(parcel);
} finally {
parcel.recycle();
}
}
private CharSequence appendTail(SpannableStringBuilder builder) {
builder.append(mSource.subSequence(mAppendPosition, mSource.length()));
return builder;
}
}