Android之玩转View(三):使用Paint实现的文字绘制(文字的基线)

使用Paint实现的文字绘制(文字的基线)

请尊重原创,转载请注明出处【tianyl】的博客

关于的Android之玩转View目录

前言

上篇文章介绍了一些使用Paint和Shader结合实现的一些特效,不过都是一些图像绘制方面的,当然,Paint除了能够进行图像绘制之外,还有另外一个功能,就是文字的绘制

当然,在学习Paint绘制文字之前,最好能够熟悉一些Paint绘制文字的api这是Paint绘制文字的常用api说明

1 文字的基线

说到文字绘制,先从一个api说起

drawText(@NonNull String text, float x, float y, @NonNull Paint paint)

这是一个常用的绘制文字的办法,可能有朋友会遇到,在使用这个方法绘制文字的时候,文字的位置经常不对,不是高了,就是低了,这就是由于这个api中的x和y造成的

看图说明


在我们绘制文字的时候,通常有上图中的六条线,分别是

  1. top:顶点线
  2. ascent:建议顶点线
  3. center:中心线
  4. baseline:基线
  5. descent:建议底部线
  6. bottom:底部线

这六条线分别起什么作用呢?

  • 首先是top和bottom,这两条线很好理解,它分别是顶端和底端,绘制文字时肯定不会超过这两条线
  • 然后是ascent和descent,这两条线是建议的顶点线和建议底端线,一般情况我们绘制文字是不会超过这两条线的,但是对于一些异形字(论坛中经常出现的跨楼层的字)是可以超出这两条线的
  • 再则是center线,这条线也很好理解,它就是top和bottom的中心
  • 最后就是基线了,这也是我们绘制文字时,传入的y坐标

1.1 基线的计算

解释了上面六条线的作用,接下来再说说这六条线是怎么计算的。

首先,我们要清楚,这六条线都是真实存在的,它们的值就保存在Paint.FontMetricsPaint.FontMetricsInt中,这两个类的值基本相似,区别是一个是float,一个是int

如图

  • Paint.FontMetrics


  • Paint.FontMetricsInt


明确了这六条线值的位置,那它们是怎么计算得来的呢?

首先说明,计算着六条线的时候,是以基线为参照物的,计算方式如下

注:在以下计算推断中,ascent,desent之类的都表示距离,ascent.y,desent.y之类的表示坐标

top.y = top.y - baseline.y
bottom.y = bottom.y - baseline.y
ascent.y = ascent.y - baseline.y
desent.y = desent.y - baseline.y
center.y = (bottom.y - top.y) / 2

因为是以baseline为参照物,所以所有的距离都是它们的y坐标和baseline的y坐标相减,
但是Paint.FontMetrics中并没有baseline的值,那么我们要怎么得到它呢

baseline的计算如图所示(网上好多图都是错的,不得不自己画了一张,(╥﹏╥))

首先,如果我们要绘制文本,那么我们可以拿到top和bottom的坐标,并且我们也知道center

  • center.y = (bottom.y - top.y) / 2

看图,我们知道top.y到center.y的距离和bottom.y到center.y的距离相同,设定这个距离为a,那么center.y到baseline.y的距离就是:a - bottom
(没有.y时表示它到baseline的距离)

所以有:

  • baseline.y - center.y = (bottom.y - top.y) / 2 - bottom.y

解得:

  • baseline.y = center.y + (bottom.y - top.y) / 2 - bottom.y

当然,同样的推理,还可以得出baseline和ascent,desent之间的关系,这里就不展开了,原理都是一样的

1.2 如何绘制文字到中心

经历了前面的长篇大论,有的同学就要问了,知道baseline的计算有什么用呢?

回到最开始的api

drawText(@NonNull String text, float x, float y, @NonNull Paint paint)

是不是有的同学在使用这个api的时候,经常遇到y值怎么设置都不能让文字处于控件中间,不是高一点就是低一点?

如果我们想把文字绘制到我们View的正中心,那么这里的y就需要传入我们计算好的baseline,代码如下

// 首先设置paint的文字大小
paint.setColor(textColor);
paint.setStrokeWidth(0);
paint.setTextSize(textSize);
paint.setTypeface(Typeface.DEFAULT_BOLD);

//根据paint的文字大小获得Paint.FontMetricsInt
Paint.FontMetricsInt fm = paint.getFontMetricsInt();

//根据Paint.FontMetricsInt计算baseline
canvas.drawText(string, getWidth() / 2 - paint.measureText(string) / 2 ,
            getHeight() / 2  +(fm.bottom - fm.top)/2 - fm.bottom, paint);

这样,就可以将文字画到垂直方向的正中心了,至于水平中心,只需要控件宽度减去文字宽度除以2就可以了

本来还想写一些文字的特效的,想来篇幅太长阅读起来体验也不太好,文字的特效就留到以后写吧

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