Android-如何让优雅地让一个TextView显示两种样式的字体

前言

这是一个很常见的需求,一般出现在有单位的数据展示上面。例如下面的两个例子,来源于我司项目的某一个页面。

image
image

如果让你实现图一的3.07万元 和图二的 您的估价低于 80% 车主的估价,你会怎么布局?

如果是以前的我:

图一的3.07万元 会换成 3.07万元 两个 TextView 显示,因为俩大小不一样,这个理由尚能接受。

图二,会换成 3 个 TextView 显示,因为颜色不一样,而且颜色不一样的还在中间。嗯,这个说出来就感觉有点丢脸了。

然而现在我想说,事实上,这两者都可以只用一个 TextView 展示。

而且方式还不只一种:

  • TextView 显示 Html 样式
  • SpannableString

下面分别用这两种方式实现一下。

Html 方式

有这么一个方法:

Html.fromHtml()

该方法可以将一段 html 字符串显示为TextView 可以显示的样式文本。

于是,首先根据需求编写好 html ,通过该方法转换文本,拿给 TextView 显示即可。

如下:

tv1.setText(Html.fromHtml("<font color=\'#217aff\' ><big>3.07</big></font><font color=\'#217aff\' ><small>万元</small></font>"));

tv2.setText(Html.fromHtml("<font color=\'#656565\'>您的估价</font><font color=\'#f48421\'>低于</font><font color=\'#656565\'>80%车主的售价。</font>"));

显示效果:

image

另外,大家注意到上面 3.07万元中两个字体大小不同,我是通过 <big>3.07</big> <small>万元</small> 去控制的。这个是因为 Android 中只支持 <font> 标签的 color 和 face 标签,不支持 size 标签。所以像下面的样式,无法显示 size 大小的。

"<font color=\'#217aff\' size=\'18px\' >3.07</font><font color=\'#217aff\' size=\'10px\'>万元</font>"

想控制大小只能通过 <big><small> 标签,但是两者的大小比较固定,没办法精确控制。如果遇到需要控制字体大小的需求,可以考虑用下面的 SpannableString 来实现。

SpannableString 方式

SpannableString 实现了 CharSequence 接口,所以无须转换, TextView 可以直接通过 setText() 方法显示。

先使用 SpannableString 实现上面的例子感受一下:

// “3.07 万元”的实现方式
SpannableString s1 = new SpannableString("3.07万元");

s1.setSpan(new AbsoluteSizeSpan(18, true), 0, s1.length()-2, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
s1.setSpan(new AbsoluteSizeSpan(10, true), s1.length()-2, s1.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);

tv3.setTextColor(Color.parseColor("#217aff"));
tv3.setText(s1);

// “80%车主的估价”的实现方式
SpannableString s2 = new SpannableString("您的估价低于80%车主的估价");

s2.setSpan(new ForegroundColorSpan(Color.parseColor("#656565")), 0, 4, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
s2.setSpan(new ForegroundColorSpan(Color.parseColor("#f48421")), 4, 6, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
s2.setSpan(new ForegroundColorSpan(Color.parseColor("#656565")), 6, s2.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);

tv4.setText(s2);

显示效果:

image

是不是很赞,来看一下实现过程:

第一步:创建一个SpannableString。

SpannableString spannableString = new SpannableString("3.07万元");

第二步:使用 setSpan() 给 SpannableString 设置样式。

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


参数的意义是:

  • what:对SpannableString进行润色的各种Span;
  • start:需要润色文字段开始的下标;
  • end:需要润色文字段结束的下标;
  • flags:标志位,决定操作的范围是否包含开始和结束下标,有四个参数可选,为什么有四个?因为分别代表着 start 至 end 的四种集合开闭模式。
    • SPAN_INCLUSIVE_EXCLUSIVE:[start,end) 包括开始下标,但不包括结束下标
    • SPAN_EXCLUSIVE_INCLUSIVE:(start,end] 不包括开始下标,但包括结束下标
    • SPAN_INCLUSIVE_INCLUSIVE:[start,end] 既包括开始下标,又包括结束下标
    • SPAN_EXCLUSIVE_EXCLUSIVE:(start,end) 不包括开始下标,也不包括结束下标

总体是第一个参数决定效果,后三个参数决定范围,显而易见,第一个参数是非常的需要去好好认识,把酒言欢一下的。

SpannableString 提供了很多 Span 样式供开发者们选择,有用来设置大小,颜色,下划线,甚至还有点击事件的。我找了它们的继承结构图,截来给大家看一下 Span 们的家谱。

image

上面例子中只用到了两个样式, ForegroundColorSpan 设置字体前景颜色,AbsoluteSizeSpan 设置字体大小,非常的简单。其实 Span 们功能远不止这些,但是这里不赘述了,大家可以自己多去尝试,下面是我觉得比较好的文章链接分享。

Android UI——SpannableString详细解析
一个实现微博那种#话题,@好友 符号表情的例子

另外一个新 Get 的小知识点

真实的项目开发中,想 3.07万元 这种字符串不可能是固定好的,肯定是有服务端返回的,但是有的只是纯数字。那么除了用 + 号拼接,还可以这样使用:

 String s = String.format("%s万元",3.07);

关于这个 String.format() 方法也是最近才发现的一个小技巧,使用上感觉比+要更方便,也更直观,关于它的更多信息可以直接看官方文档,大概了解掌握其功能,记住几个最常用的,其他的可以随用随查。

最后

哈哈哈,觉得自己之前好笨拙,可能现在也是,不过有这个感觉也证明现在变的好一点了吧,虽然是一个很小的知识点。荀子老人家说了:“不积跬步,无以至千里;不积小流,无以成江海。”,希望我们都越来越好。

下篇博客见。


期待与你一起成长
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,242评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,769评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,484评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,133评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,007评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,080评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,496评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,190评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,464评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,549评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,330评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,205评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,567评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,889评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,160评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,475评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,650评论 2 335

推荐阅读更多精彩内容