Android(安卓)Span 的使用
字体规格(Font Metrics)
- 如果你想知道更多什么是字体规格,那么看下面的图解:
BulletSpan
- android.text.style.BulletSpan
BulletSpan影响段落层次的文本格式。它可以给段落的开始处加上项目符号。
/*** gapWidth:项目符号和文本之间的间隙* color: 项目符号的颜色,默认为透明*///创建一个黑色的BulletSpan,间隙为15pxspan = new BulletSpan(15, Color.BLACK);
QuoteSpan
- android.text.style.QuoteSpan
QuoteSpan影响段落层次的文本格式。它可以给一个段落加上垂直的引用线。
/*** color: 垂直的引用线颜色,默认是蓝色*///创建一个红色的引用span = new QuoteSpan(Color.RED);
QuoteSpan
- android.text.style.AlignmentSpan.Standard
AlignmentSpan.Standard影响段落层次的文本格式。它可以把段落的每一行文本按正常、居中、相反的方式对齐。
/*** align: 对齐方式*///居中对齐的段落span = new AlignmentSpan.Standard(Layout.Alignment.ALIGN_CENTER);
UnderlineSpan
- android.text.style.UnderlineSpan
UnderlineSpan影响字符级的文本格式。它可以为字符集加上下划线,归功于Paint#setUnderlineText(true))。
//下划线span = new UnderlineSpan();
StrikethroughSpan
- android.text.style.StrikethroughSpan
StrikethroughSpan影响字符级的文本格式。它可以给字符集加上删除线,归功于Paint#setStrikeThruText(true))。
//删除线span = new StrikethroughSpan();
SubscriptSpan
- android.text.style.SubscriptSpan
SubscriptSpan影响字符级的文本格式,它可以通过减小TextPaint#baselineShift给字符集加下标。
//下标span = new SubscriptSpan();
BackgroundColorSpan
- android.text.style.BackgroundColorSpan
BackgroundColorSpan影响字符级的文本格式。它可以给字符集加上背景颜色。
/*** color: 背景颜色*///设置字符背景颜色span = new BackgroundColorSpan(Color.GREEN);
ForegroundColorSpan
- android.text.style.ForegroundColorSpan
ForegroundColorSpan影响字符级的文本格式,它可以设置字符集的前景颜色也即文字颜色。
/*** color: 前景颜色*///设置红色的前景span = new ForegroundColorSpan(Color.RED);
ImageSpan
- android.text.style.ImageSpan
ImageSpan影响字符级的文本格式。它可以生成图像字符。这是为数不多的文档齐全的Span所以enjoy it!
/*** Context: 上下文* resourceId: 图像资源id*///用一个小图像代替字符span = new ImageSpan(this, R.drawable.pic1_small);
StyleSpan
- android.text.style.StyleSpan
StyleSpan影响字符级的文本格式,它可以给字符集设置样式(blod、italic、normal)。
//设置bold+italic的字符样式span = new StyleSpan(Typeface.BOLD | Typeface.ITALIC);
TypefaceSpan
- android.text.style.TypefaceSpan
TypefaceSpan影响字符级的文本格式。它可以给字符设置字体集(monospace、serif等)。
//设置serif familyspan = new TypefaceSpan("serif");
TextAppearanceSpan
- android.text.style.TextAppearanceSpan
TextAppearanceSpan影响字符级的文本格式。它可以给字符集设置外观(appearance)。
/*** TextAppearanceSpan(Context context, int appearance, int colorList)* context: 上下文* appearance:appearance资源id(例如:android.R.style.TextAppearance_Small)* colorList:文本的颜色资源id(例如:android.R.styleable.Theme_textColorPrimary)** TextAppearanceSpan(String family, int style, int size, ColorStateList color, ColorStateList linkColor)* family:字体family* style:描述样式(例如:android.graphics.Typeface)* size:文字大小* color:文字颜色* linkColor:连接文本的颜色*///设置serif familyspan = new TextAppearanceSpan(this/*a context*/, R.style.SpecialTextAppearance);<-- style.xml -->
AbsoluteSizeSpan
- android.text.style.AbsoluteSizeSpan
AbsoluteSizeSpan影响字符级的文本格式。它可以设置一个字符集的绝对文字大小。
/*** size: 大小* dip: false,size单位为px,true,size单位为dip(默认为false)。*///设置文字大小为24dpspan = new AbsoluteSizeSpan(24, true);
RelativeSizeSpan
- android.text.style.RelativeSizeSpan
RelativeSizeSpan影响字符水平的文本格式。它可以设置字符集的文本大小。
//设置文字大小为大2倍span = new RelativeSizeSpan(2.0f);
ScaleXSpan
- android.text.style.ScaleXSpan
ScaleXSpan印象字符集的文本格式。它可以在x轴方向上缩放字符集。
//设置水平方向上放大3倍span = new ScaleXSpan(3.0f);
MaskFilterSpan
- android.text.style.MaskFilterSpan
- MaskFilterSpan影响字符集文本格式。它可以给字符集设置android.graphics.MaskFilter。
警告:BlurMaskFilter不支持硬件加速
//模糊字符集span = new MaskFilterSpan(new BlurMaskFilter(density*2, BlurMaskFilter.Blur.NORMAL));//浮雕字符集span = new MaskFilterSpan(new EmbossMaskFilter(new float[] { 1, 1, 1 }, 0.4f, 6, 3.5f));
MaskFilterSpan的效果图: BlurMaskFilter
- MaskFilterSpan的效果图: EmbossMaskFilter
Spans进阶
- 前景色(文字颜色)动画
- 前景色(文字颜色)动画
ForegroundColorSpan为只读。这意味实例化之后着你不能改变你不能改变前景色。所以,要做的第一件事就是编写一个MutableForegroundColorSpan。(不固定的)
MutableForegroundColorSpan.java
public class MutableForegroundColorSpan extends ForegroundColorSpan { private int mAlpha = 255; private int mForegroundColor; public MutableForegroundColorSpan(int alpha, int color) { super(color); mAlpha = alpha; mForegroundColor = color; } public MutableForegroundColorSpan(Parcel src) { super(src); mForegroundColor = src.readInt(); mAlpha = src.readInt(); } public void writeToParcel(Parcel dest, int flags) { super.writeToParcel(dest, flags); dest.writeInt(mForegroundColor); dest.writeFloat(mAlpha); } @Override public void updateDrawState(TextPaint ds) { ds.setColor(getForegroundColor()); } /** * @param alpha from 0 to 255 */ public void setAlpha(int alpha) { mAlpha = alpha; } public void setForegroundColor(int foregroundColor) { mForegroundColor = foregroundColor; } public float getAlpha() { return mAlpha; } @Override public int getForegroundColor() { return Color.argb(mAlpha, Color.red(mForegroundColor), Color.green(mForegroundColor), Color.blue(mForegroundColor)); }}
现在,我们可以在同一个实例改变透明度和前景色了。但是,当你设置这些属性,它并不会刷新视图,你必须通过重新设置SpannableString才能刷新视图。
MutableForegroundColorSpan span = new MutableForegroundColorSpan(255, Color.BLACK);spannableString.setSpan(span, 0, text.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);textView.setText(spannableString);//黑色完全不透明(译者注:上面代码的效果)span.setAlpha(100);span.setForegroundColor(Color.RED);//到这一步文字没有变化textView.setText(spannableString);//最后,文字变为红色和透明
现在我们要前景色的动画。我们可以自定义android.util.Property。
private static final Property
MUTABLE_FOREGROUND_COLOR_SPAN_FC_PROPERTY =new Property (Integer.class, "MUTABLE_FOREGROUND_COLOR_SPAN_FC_PROPERTY") { @Override public void set(MutableForegroundColorSpan span, Integer value) { span.setForegroundColor(value); } @Override public Integer get(MutableForegroundColorSpan span) { return span.getForegroundColor(); }}; 最后,我们使用属性动画(ObjectAnimator)让自定义属性动起来。不要忘记更新视图。
MutableForegroundColorSpan span = new MutableForegroundColorSpan(255, Color.BLACK);mSpannableString.setSpan(span, 0, text.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);ObjectAnimator objectAnimator = ObjectAnimator.ofInt(span, MUTABLE_FOREGROUND_COLOR_SPAN_FC_PROPERTY, Color.BLACK, Color.RED);objectAnimator.setEvaluator(new ArgbEvaluator());objectAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { //refresh mText.setText(mSpannableString); }});objectAnimator.start();
ActionBar”烟火”
“烟 火”动画是让文字随机淡入。首先,把文字切断成多个spans(例如,一个character的span),淡入spans后再淡入其它的spans。用前面介绍的MutableForegroundColorSpan,我们将创建一组特殊的span对象。在span组调用对应的setAlpha方法,我们随机设置每个span的透明度。
private static final class FireworksSpanGroup { private final float mAlpha; private final ArrayList
mSpans; private FireworksSpanGroup(float alpha) { mAlpha = alpha; mSpans = new ArrayList (); } public void addSpan(MutableForegroundColorSpan span) { span.setAlpha((int) (mAlpha * 255)); mSpans.add(span); } public void init() { Collections.shuffle(mSpans); } public void setAlpha(float alpha) { int size = mSpans.size(); float total = 1.0f * size * alpha; for(int index = 0 ; index < size; index++) { MutableForegroundColorSpan span = mSpans.get(index); if(total >= 1.0f) { span.setAlpha(255); total -= 1.0f; } else { span.setAlpha((int) (total * 255)); total = 0.0f; } } } public float getAlpha() { return mAlpha; }} 我们创建一个自定义属性动画的属性去更改FireworksSpanGroup的透明度
private static final Property
FIREWORKS_GROUP_PROGRESS_PROPERTY =new Property (Float.class, "FIREWORKS_GROUP_PROGRESS_PROPERTY") { @Override public void set(FireworksSpanGroup spanGroup, Float value) { spanGroup.setProgress(value); } @Override public Float get(FireworksSpanGroup spanGroup) { return spanGroup.getProgress(); }}; 最后,我们创建span组并使用一个ObjectAnimator给其加上动画。
final FireworksSpanGroup spanGroup = new FireworksSpanGroup();//初始化包含多个spans的grop//spanGroup.addSpan(span);//给ActionBar的标题设置spans//mActionBarTitleSpannableString.setSpan(span, start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);spanGroup.init();ObjectAnimator objectAnimator = ObjectAnimator.ofFloat(spanGroup, FIREWORKS_GROUP_PROGRESS_PROPERTY, 0.0f, 1.0f);objectAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener(){ @Override public void onAnimationUpdate(ValueAnimator animation) { //更新标题 setTitle(mActionBarTitleSpannableString); }});objectAnimator.start();
使用自定义的span
- 在本节中,我们将看到使用自定义span来绘制的方式。这是文本定制很好的方式。
首先,我们要创建一个继承ReplacementSpan抽象类的自定义Span。
如果你想画一个自定义的背景,你可以实现LineBackgroundSpan
,这是影响段落级的文本格式。我们必须实现2个方法:
getSize):这个方法返回新的你更换后的size。text:Span管理的文本start:文本开始处end:文本结尾处fm:字体规格,可以为空draw):可以使用Canvas绘制。x:绘制文本的x坐标top:线(line)的顶部(译者注:line的定义参看前面字体规格这一节)y:基线bottom:线的底部、
让我们看一个例子,画一个包围文本的蓝色矩形。
FrameSpan.java@Overridepublic int getSize(Paint paint, CharSequence text, int start, int end, Paint.FontMetricsInt fm){ //将返回相对于Paint画笔的文本 mWidth = (int) paint.measureText(text, start, end); return mWidth;}@Overridepublic void draw(Canvas canvas, CharSequence text, int start, int end, float x, int top, int y, int bottom, Paint paint){ //使用自定义的画笔绘制在画布上 canvas.drawRect(x, top, x + mWidth, bottom, mPaint);}
附加
Sample app包含了一些Spans进阶的例子,如下:
- Progressive blur
- Typewriter
更多相关文章
- AndroidStudio使用[原创]
- 搜索框(SearchView)用法
- Android(安卓)——真机调试
- 使用Canvas的drawTextOnPath方法实现沿着Path绘制文本
- android emulator 通过代理访问web service
- AdapterViewFlipper实现跑马灯横幅广告滚动效果
- android webvie使用技巧
- 【转】Notification 详解
- "奇葩家园“之genymotion工具篇