字体规格(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

更多相关文章

  1. AndroidStudio使用[原创]
  2. 搜索框(SearchView)用法
  3. Android(安卓)——真机调试
  4. 使用Canvas的drawTextOnPath方法实现沿着Path绘制文本
  5. android emulator 通过代理访问web service
  6. AdapterViewFlipper实现跑马灯横幅广告滚动效果
  7. android webvie使用技巧
  8. 【转】Notification 详解
  9. "奇葩家园“之genymotion工具篇

随机推荐

  1. 刚学习android安卓,哪里有源码例子可以下
  2. Android实现自定义相机系列(1)—自定义vi
  3. 研究Android即时聊天、实时语音通话、实
  4. 初学Android应用程序——资源文件、文字
  5. Android绘图机制与处理技巧(三)——Android
  6. Android(安卓)NDK编译带STL的 C/C++ 程序
  7. Android 之UI自适应解决方案
  8. adb shell 调试 Android 串口
  9. 还原Android彩信数据库
  10. Android中利用Handler实现消息的分发机制