Android SpannableString详细解析,Android工程师面试题及答案

54 阅读5分钟

什么是SpannableString?


SpannableString,是CharSequence的一种,原本的CharSequence只是一串字符序列,没有任何样式,而SpannableString可以在字符序列基础上对指定的字符进行润饰,在开发中,TextView可以通过setText(CharSequence)传入SpannableString作为参数,来达到显示不同样式文字的效果。

创建方式

SpannableString spannableString = new SpannableString("如果我是陈奕迅");

如何对SpannableString进行润饰?

一般通过以下方式进行设置

spannableString.setSpan(Object what, int start, int end, int flags);

这里讲解一下几个参数的意义

  • what:对SpannableString进行润色的各种Span

  • int:需要润色文字段开始的下标;

  • end:需要润色文字段结束的下标;

  • flags:决定开始和结束下标是否包含的标志位,有四个参数可选

  • SPAN_INCLUSIVE_EXCLUSIVE:包括开始下标,但不包括结束下标

  • SPAN_EXCLUSIVE_INCLUSIVE:不包括开始下标,但包括结束下标

  • SPAN_INCLUSIVE_INCLUSIVE:既包括开始下标,又包括结束下标

  • SPAN_EXCLUSIVE_EXCLUSIVE:不包括开始下标,也不包括结束下标

这里涉及到一个重要的角色,就是各种各样的span,它决定我们要对文字的进行怎样的润饰,而后三个参数决定润饰哪些文字,为了方便起见,后面的flags默认都使用SPAN_INCLUSIVE_EXCLUSIVE模式。

各种Span


先来看一张类结构图,了解各种Span之间的关系

在这里插入图片描述

可以看出所有Span都继承于CharacterStyle这个抽象类,另外MetricAffectingSpan、ReplacementSpan和ClickableSpan都是抽象类,下面展示一些常用的Span

ForegroundColorSpan 前景色


SpannableString spannableString = new SpannableString("如果我是陈奕迅");

ForegroundColorSpan foregroundColorSpan = new ForegroundColorSpan(Color.GREEN);

spannableString.setSpan(foregroundColorSpan, 4, 7, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);

mTextView.setText(spannableString);

ForegroundColorSpan:前景色,也就是对文字上色,颜色设置为GREEN,start为4,end为7,应该是“陈奕迅”三个字显示为绿色,看一下实际效果

在这里插入图片描述

BackgroudColorSpan 背景色


SpannableString spannableString = new SpannableString("如果我是陈奕迅");

BackgroundColorSpan backgroundColorSpan = new BackgroundColorSpan(Color.GREEN);

spannableString.setSpan(backgroundColorSpan, 4, 7, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);

mTextView.setText(spannableString);

BackgroudColorSpan:与ForegroundColorSpan类似,对文字背景上色

在这里插入图片描述

ClickableSpan 点击事件


SpannableString spannableString = new SpannableString("如果我是陈奕迅");

ClickableSpan clickableSpan = new ClickableSpan() {

@Override

public void onClick(View widget) {

Toast.makeText(MainActivity.this, "如果我是陈奕迅", Toast.LENGTH_SHORT).show();

}

@Override

public void updateDrawState(TextPaint ds) {

ds.setUnderlineText(false);

}

};

spannableString.setSpan(clickableSpan, 4, 7, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);

mTextView.setMovementMethod(LinkMovementMethod.getInstance());

mTextView.setText(spannableString);

ClickableSpan:是一个抽象类,实现可点击效果,可以重写onClick方法实现点击事件,这里点击“陈奕迅”三个字简单地弹toast

在这里插入图片描述

URLSpan 超链接


SpannableString spannableString = new SpannableString("如果我是陈奕迅");

URLSpan urlSpan = new URLSpan("www.baidu.com/s?ie=UTF-8&…");

spannableString.setSpan(urlSpan, 4, 7, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);

mTextView.setMovementMethod(LinkMovementMethod.getInstance());

mTextView.setText(spannableString);

URLSpan:实现超链接的效果,继承于ClickableSpan,点击实现跳转到浏览器

在这里插入图片描述

MaskFilterSpan 模糊 浮雕


SpannableString spannableString = new SpannableString("如果我是陈奕迅");

MaskFilterSpan embossMaskFilterSpan =

new MaskFilterSpan(new EmbossMaskFilter(new float[]{10, 10, 10}, 0.5f, 1, 1));

spannableString.setSpan(embossMaskFilterSpan, 0, 4, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);

RelativeSizeSpan relativeSizeSpan = new RelativeSizeSpan(1.5f);

spannableString.setSpan(relativeSizeSpan, 0, 4, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);

MaskFilterSpan blurMaskFilterSpan = new MaskFilterSpan(new BlurMaskFilter(10, Blur.NORMAL));

spannableString.setSpan(blurMaskFilterSpan, 4, 7, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);

mTextView.setText(spannableString);

MaskFilterSpan:构造方法接受MaskFilter作为参数,其中它有两个子类:EmbossMaskFilter和BlurMaskFilter

EmbossMaskFilter实现浮雕效果

EmbossMaskFilter(float[] direction, float ambient, float specular, float blurRadius)

  • direction:float数组,定义长度为3的数组标量[x,y,z],来指定光源的方向

  • ambient:环境光亮度,0~1

  • specular:镜面反射系数

  • blurRadius:模糊半径,必须>0

BlurMaskFilter实现模糊效果

BlurMaskFilter(float radius, Blur style)

  • radius:模糊半径

  • style:有四个参数可选

  • BlurMaskFilter.Blur.NORMAL:内外模糊

  • BlurMaskFilter.Blur.OUTER:外部模糊

  • BlurMaskFilter.Blur.INNER:内部模糊

  • BlurMaskFilter.Blur.SOLID:内部加粗,外部模糊

在这里插入图片描述

RelativeSizeSpan 字体相对大小


SpannableString spannableString = new SpannableString("如果我是陈奕迅");

RelativeSizeSpan relativeSizeSpan = new RelativeSizeSpan(1.5f);

spannableString.setSpan(relativeSizeSpan, 4, 7, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);

mTextView.setText(spannableString);

RelativeSizeSpan:设置字体的相对大小,这里设置为TextView大小的1.5倍,看图

在这里插入图片描述

AbsoluteSizeSpan 字体绝对大小


SpannableString spannableString = new SpannableString("如果我是陈奕迅");

AbsoluteSizeSpan absoluteSizeSpan = new AbsoluteSizeSpan(40, true);

spannableString.setSpan(absoluteSizeSpan, 4, 7, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);

mTextView.setText(spannableString);

AbsoluteSizeSpan:设置字体的相绝对大小,40表示文字大小,true表示单位为dip,若为false则表示px

在这里插入图片描述

ScaleXSpan 字体x轴缩放


SpannableString spannableString = new SpannableString("如果我是陈奕迅");

ScaleXSpan scaleXSpan= new ScaleXSpan(1.5f);

spannableString.setSpan(scaleXSpan, 4, 7, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);

mTextView.setText(spannableString);

ScaleXSpan:设置字体x轴缩放,1.5表示x轴放大为1.5倍,效果如图

在这里插入图片描述

StyleSpan 样式


SpannableString spannableString = new SpannableString("如果我是陈奕迅");

StyleSpan boldSpan = new StyleSpan(Typeface.BOLD);

StyleSpan italicSpan = new StyleSpan(Typeface.ITALIC);

StyleSpan boldItalicSpan = new StyleSpan(Typeface.BOLD_ITALIC);

spannableString.setSpan(boldSpan, 0, 2, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);

spannableString.setSpan(italicSpan, 2, 4, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);

spannableString.setSpan(boldItalicSpan, 4, 7, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);

mTextView.setText(spannableString);

StyleSpan:设置文字样式,如斜体、粗体

在这里插入图片描述

TypefaceSpan 字体


SpannableString spannableString = new SpannableString("如果我是陈奕迅");

TypefaceSpan monospace = new TypefaceSpan("monospace");

写在最后

对程序员来说,很多技术的学习都是“防御性”的。也就是说,我们是在为未来学习。我们学习新技术的目的,或是为了在新项目中应用,或仅仅是为了将来的面试。但不管怎样,一定不能“止步不前”,不能荒废掉。

![ []

文章以下内容会给出阿里与美团的面试题(答案+解析)、面试题库、Java核心知识点梳理等,需要这些文档资料的,直接点击我的GitHub免费领取~