最近受到大佬的影響,決定來寫寫東西,記錄一下自己平時(shí)學(xué)習(xí)工作中遇到的一些東西。第一次在簡(jiǎn)書上寫東西,逼近還是第一次么,難免還是有一些緊張激動(dòng)。
俗話說男人就怕太快了,所以希望自己也能多堅(jiān)持堅(jiān)持,把寫東西這個(gè)事情堅(jiān)持久一點(diǎn)吧。
好了,瞎扯完了,開始。
第一篇就先寫一個(gè)Android中如何在一個(gè)TextView中給文字設(shè)置不同的樣式吧。
都知道Android開發(fā)中用于顯示文字最簡(jiǎn)單的View就是Textview了,調(diào)用setText()函數(shù)設(shè)置文字。如果你需要給同一個(gè)TextView中的文字設(shè)置不同的樣式的話,就可以使用SpannableString這個(gè)類來完成。(當(dāng)然還有很多其他的方式)
SpannableString是什么
/**
* This is the class for text whose content is immutable but to which
* markup objects can be attached and detached.
* For mutable text, see {@link SpannableStringBuilder}.
*/
public class SpannableString
extends SpannableStringInternal
implements CharSequence, GetChars, Spannable
{
public SpannableString(CharSequence source) {
super(source,0, source.length());
}
private SpannableString(CharSequence source,int start,int end) {
super(source, start, end);
}
public static SpannableString valueOf(CharSequence source) {
if (sourceinstanceof SpannableString) {
return (SpannableString) source;
}else {
return new SpannableString(source);
}
}
public void setSpan(Object what,int start,int end,int flags) {
super.setSpan(what, start, end, flags);
}
public void removeSpan(Object what) {
super.removeSpan(what);
}
public final CharSequence subSequence(int start,int end) {
return new SpannableString(this, start, end);
}
}
從SpannableString的源碼中可以看出,其實(shí)SpannableString,是CharSequence的一種。而原本的CharSequence是一串沒有樣式的字符串序列。而SpannableString就可以做到在原有的字符串序列的基礎(chǔ)上對(duì)指定位置的字符進(jìn)行裝飾。我們?cè)诮o就可以使用setText(SpannableString),SpannableString作為參數(shù),從而達(dá)到不同的顯示樣式。
創(chuàng)建一個(gè)SpannableString對(duì)象。
SpannableString spannableString = new SpannableString("使用SpannableString設(shè)置不同的文字樣式");
怎么使用SpannableString設(shè)置字體樣式
public void setSpan(Object what, int start, int end, int flags) {
super.setSpan(what, start, end, flags);
}
textview.setText(spannableString);
這個(gè)方法有四個(gè)參數(shù):
-
Object what:對(duì)SpannableString進(jìn)行裝飾的span,可以理解成不同的各種樣式(常見span有:ForegroundColorSpan,BackgroudColorSpan,ClickableSpan,URLSpan,MaskFilterSpan,RelativeSizeSpan等等,后面回給出集中實(shí)例樣式)
各種Span int start:使用樣式效果的起始下標(biāo)位置
int end: 使用樣式效果的結(jié)束下標(biāo)位置
-
int flags:決定開始和結(jié)束下標(biāo)是否包含的標(biāo)志位。簡(jiǎn)單點(diǎn)就是一個(gè)使用樣式的一個(gè)區(qū)間。這個(gè)參數(shù)用四個(gè)固定的值可以讓我們選擇
- SPAN_INCLUSIVE_EXCLUSIVE:包括開始下標(biāo),但不包括結(jié)束下標(biāo)。區(qū)間表示:[start,end)
- SPAN_EXCLUSIVE_INCLUSIVE:不包括開始下標(biāo),但包括結(jié)束下標(biāo)。區(qū)間表示:(start,end]
- SPAN_INCLUSIVE_INCLUSIVE:既包括開始下標(biāo),又包括結(jié)束下標(biāo)。區(qū)間表示:[start,end]
- SPAN_EXCLUSIVE_EXCLUSIVE:不包括開始下標(biāo),也不包括結(jié)束下標(biāo)。區(qū)間表示:(start,end)
不同的Span樣式實(shí)例
先看一張效果

ForegroundColorSpan:前景色,也就是給指定的文字上色。
效果對(duì)應(yīng)上圖的第一個(gè)TextView
ForegroundColorSpan參數(shù):@ColorInt int color。只需要傳入顏色即可
SpannableString spannableString = new SpannableString("使用SpannableString設(shè)置不同的文字樣式");
ForegroundColorSpan foregroundColorSpan = new ForegroundColorSpan(Color.RED);
spannableString.setSpan(foregroundColorSpan, 2, 17, Spanned.SPAN_INCLUSIVE_INCLUSIVE);
tv1.setText(spannableString);
BackgroundColorSpan:背景色,也就是給指定的文字的背景上色。
BackgroundColorSpan參數(shù):@ColorInt int color。只需要傳入顏色即可
SpannableString spannableString2 = new SpannableString("使用SpannableString設(shè)置不同的文字樣式");
BackgroundColorSpan backgroundColorSpan = new BackgroundColorSpan(Color.GREEN);
spannableString2.setSpan(backgroundColorSpan, 2, 17, Spanned.SPAN_INCLUSIVE_INCLUSIVE);
tv2.setText(spannableString2);
MaskFilterSpan:一種模糊效果。
MaskFilterSpan參數(shù):MaskFilter filter。
SpannableString spannableString3 = new SpannableString("使用SpannableString設(shè)置不同的文字樣式");
MaskFilterSpan embossMaskFilterSpan = new MaskFilterSpan(new EmbossMaskFilter(new float[]{10, 10, 10}, 0.5f, 1, 1));
spannableString3.setSpan(embossMaskFilterSpan, 2, 17, Spanned.SPAN_INCLUSIVE_INCLUSIVE);
RelativeSizeSpan relativeSizeSpan = new RelativeSizeSpan(1.5f);
spannableString3.setSpan(relativeSizeSpan, 2, 17, Spanned.SPAN_INCLUSIVE_INCLUSIVE);
MaskFilterSpan blurMaskFilterSpan = new MaskFilterSpan(new BlurMaskFilter(10, BlurMaskFilter.Blur.NORMAL));
spannableString3.setSpan(blurMaskFilterSpan, 2, 17, Spanned.SPAN_INCLUSIVE_INCLUSIVE);
tv3.setText(spannableString3);
而MaskFilter有兩個(gè)子類:EmbossMaskFilter和BlurMaskFilter
EmbossMaskFilter:實(shí)現(xiàn)一種浮雕的效果
public EmbossMaskFilter(float[] direction, float ambient, float specular, float blurRadius) {
if (direction.length < 3) {
throw new ArrayIndexOutOfBoundsException();
}
native_instance = nativeConstructor(direction, ambient, specular, blurRadius);
}
從EmbossMaskFilter的源碼中可以看見它需要4個(gè)參數(shù)
- float[] direction:一個(gè)長(zhǎng)度為3的float數(shù)組,定義出光源的方向
- float ambient:取值范圍0~1,定義環(huán)境光的強(qiáng)度
- float specular:反射系數(shù)
- float blurRadius:必須大于0,模糊半徑
BlurMaskFilter:實(shí)現(xiàn)一種模糊的效果
/**
* Create a blur maskfilter.
*
* @param radius The radius to extend the blur from the original mask. Must be > 0.
* @param style The Blur to use
* @return The new blur maskfilter
*/
public BlurMaskFilter(float radius, Blur style) {
native_instance = nativeConstructor(radius, style.native_int);
}
從BlurMaskFilter的源碼中可以看見它需要2個(gè)參數(shù)
- float radius:模糊半徑
- Blur style:模糊樣式,四個(gè)值可選
public enum Blur {
/**
* Blur inside and outside the original border.
*/
NORMAL(0),
/**
* Draw solid inside the border, blur outside.
*/
SOLID(1),
/**
* Draw nothing inside the border, blur outside.
*/
OUTER(2),
/**
* Blur inside the border, draw nothing outside.
*/
INNER(3);
Blur(int value) {
native_int = value;
}
final int native_int;
}
BlurMaskFilter.Blur.NORMAL:內(nèi)外模糊
BlurMaskFilter.Blur.OUTER:外部模糊
BlurMaskFilter.Blur.INNER:內(nèi)部模糊
BlurMaskFilter.Blur.SOLID:內(nèi)部加粗,外部模糊
RelativeSizeSpan:改變字體的相對(duì)大小。
SpannableString spannableString4 = new SpannableString("使用SpannableString設(shè)置不同的文字樣式");
RelativeSizeSpan relativeSizeSpan2 = new RelativeSizeSpan(2f);
spannableString4.setSpan(relativeSizeSpan2, 2, 17, Spanned.SPAN_INCLUSIVE_INCLUSIVE);
tv4.setText(spannableString4);
ScaleXSpan:相對(duì)X軸對(duì)字體的寬度進(jìn)行縮放。
SpannableString spannableString5 = new SpannableString("使用SpannableString設(shè)置不同的文字樣式");
ScaleXSpan scaleXSpan= new ScaleXSpan(2f);
spannableString5.setSpan(scaleXSpan, 2, 17, Spanned.SPAN_INCLUSIVE_INCLUSIVE);
tv5.setText(spannableString5);
TextAppearanceSpan:設(shè)置文字樣式,通過style資源設(shè)置。
SpannableString spannableString6 = new SpannableString("使用SpannableString設(shè)置不同的文字樣式");
TextAppearanceSpan textAppearanceSpan = new TextAppearanceSpan(this, android.R.style.TextAppearance_Material);
spannableString6.setSpan(textAppearanceSpan, 2, 17, Spanned.SPAN_INCLUSIVE_INCLUSIVE);
tv6.setText(spannableString6);
UnderlineSpan:給文字添加下劃線。
SpannableString spannableString7 = new SpannableString("使用SpannableString設(shè)置不同的文字樣式");
UnderlineSpan underlineSpan = new UnderlineSpan();
spannableString7.setSpan(underlineSpan, 2, 17, Spanned.SPAN_INCLUSIVE_INCLUSIVE);
tv7.setText(spannableString7);
StrikethroughSpan:給文字添加刪除線。
SpannableString spannableString8 = new SpannableString("使用SpannableString設(shè)置不同的文字樣式");
StrikethroughSpan strikethroughSpan = new StrikethroughSpan();
spannableString8.setSpan(strikethroughSpan, 2, 17, Spanned.SPAN_INCLUSIVE_INCLUSIVE);
tv8.setText(spannableString8);
URLSpan:給文字添加一個(gè)超鏈接,點(diǎn)擊跳轉(zhuǎn)至指定的url。
SpannableString spannableString9 = new SpannableString("使用SpannableString設(shè)置不同的文字樣式");
URLSpan urlSpan = new URLSpan("https://www.baidu.com");
spannableString9.setSpan(urlSpan, 2, 17, Spanned.SPAN_INCLUSIVE_INCLUSIVE);
tv9.setMovementMethod(LinkMovementMethod.getInstance());
tv9.setText(spannableString9);
clickableSpan:給文字添加一個(gè)點(diǎn)擊區(qū)域。ClickableSpan是一個(gè)抽象類,實(shí)現(xiàn)可點(diǎn)擊效果,操作時(shí)可以重寫onClick方法實(shí)現(xiàn)點(diǎn)擊事件
SpannableString spannableString10 = new SpannableString("使用SpannableString設(shè)置不同的文字樣式");
ClickableSpan clickableSpan = new ClickableSpan() {
@Override
public void onClick(View widget) {
Toast.makeText(MyCourseActivity.this, "SpannableString", Toast.LENGTH_SHORT).show();
}
@Override
public void updateDrawState(TextPaint ds) {
ds.setUnderlineText(false);
}
};
spannableString10.setSpan(clickableSpan, 2, 17, Spanned.SPAN_INCLUSIVE_INCLUSIVE);
tv10.setMovementMethod(LinkMovementMethod.getInstance());
tv10.setText(spannableString10);
(注意:這里我也只是例舉了幾種簡(jiǎn)單的效果,還有很多就不一一展示了。同時(shí)這些各種各樣的Span也是可以組合使用,實(shí)現(xiàn)一些比較復(fù)雜的樣式,一切只需要按照需求進(jìn)行使用即可。)
