专栏首页恩蓝脚本Android Canvas的drawText()与文字居中方案详解

Android Canvas的drawText()与文字居中方案详解

自定义View是绘制文本有三类方法

// 第一类
public void drawText (String text, float x, float y, Paint paint)
public void drawText (String text, int start, int end, float x, float y, Paint paint)
public void drawText (CharSequence text, int start, int end, float x, float y, Paint paint)
public void drawText (char[] text, int index, int count, float x, float y, Paint paint)

// 第二类
public void drawPosText (String text, float[] pos, Paint paint)
public void drawPosText (char[] text, int index, int count, float[] pos, Paint paint)

// 第三类
public void drawTextOnPath (String text, Path path, float hOffset, float vOffset, Paint paint)
public void drawTextOnPath (char[] text, int index, int count, Path path, float hOffset, float vOffset, Paint paint)

其中drawText()最常用,drawPosText ()是根据一个个坐标点指定文字位置,drawTextOnPath ()是根据路径绘制。但drawText()的x,y参数是干嘛的呢?

先来测试下

Paint paint=new Paint();
 paint.setStyle(Paint.Style.FILL);
 paint.setStrokeWidth(12);
 paint.setTextSize(100);

 String text="测试:my text";
 canvas.drawText(text, 200, 400, paint);

 //画两条线标记位置
 paint.setStrokeWidth(4);
 paint.setColor(Color.RED);
 canvas.drawLine(0, 400, 2000, 400, paint);
 paint.setColor(Color.BLUE);
 canvas.drawLine(200, 0, 200, 2000, paint);

左对齐-left

可以看到,x,y并不是指定文字的中点位置,并且x,y与文字对齐方式有关(通过setTextAlign()指定,默认为left)

居中对齐-center

右对齐-right

(为了使文字完整,上面调整了下x,y的值)

从上面三种情况得出结论,x所对应的竖线:

  • 左对齐 — 文字的左边界
  • 居中对齐 — 文字的中心位置
  • 右对齐 — 文字的左边界

y对应的横线并不是文字的下边界,而是基准线Baseline

看下面这张图

红色的Baseline是基准线,紫色的Top是文字的最顶部,也就是在drawText()中指定的x所对应,橙色的Bottom是文字的底部。

拿这些值如何获取呢?

Paint.FontMetrics fontMetrics=paint.getFontMetrics();
 fontMetrics.top
 fontMetrics.ascent
 fontMetrics.descent
 fontMetrics.bottom

记得要在设置完Paint的文字大小,宽度之类属性后再获取FontMetrics, baseline对应对应值为0,在它下面的descent和bottom值为正,top和ascent为负。那文字的高度为bottom – top

所以,实际绘制的时候取决于基线上一个点来绘制文字,而这个点有三种分别对应为left,center,right

好啦,把drawText()中x,y参数讲清楚后实现文字居中就很容易了

直接上代码

//矩形背景
 Paint bgRect=new Paint();
 bgRect.setStyle(Paint.Style.FILL);
 bgRect.setColor(Color.YELLOW);
 RectF rectF=new RectF(200, 200, 800, 600);
 canvas.drawRect(rectF, bgRect);

 Paint textPaint=new Paint();
 textPaint.setStyle(Paint.Style.FILL);
 textPaint.setStrokeWidth(8);
 textPaint.setTextSize(50);
 textPaint.setTextAlign(Paint.Align.CENTER);

 String text="测试:my text";
 //计算baseline
 Paint.FontMetrics fontMetrics=textPaint.getFontMetrics();
 float distance=(fontMetrics.bottom - fontMetrics.top)/2 - fontMetrics.bottom;
 float baseline=rectF.centerY()+distance;
 canvas.drawText(text, rectF.centerX(), baseline, textPaint);

效果

将对齐方式设置为center,那要让文字居中显示,x值就为矩形中心x值,y值也就是baseline的计算看下图

y = 矩形中心y值 + 矩形中心与基线的距离

距离 = 文字高度的一半 - 基线到文字底部的距离(也就是bottom)
 = (fontMetrics.bottom - fontMetrics.top)/2 - fontMetrics.bottom

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对ZaLou.Cn的支持。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Android编程基于自定义view实现公章效果示例【附源码下载】

    本文实例讲述了Android编程基于自定义view实现公章效果。分享给大家供大家参考,具体如下:

    砸漏
  • Android Canvas drawText文字居中的一些事(图解)

    在实现自定义控件的过程中,常常会有绘制居中文字的需求,于是在网上搜了一些相关的博客,总是看的一脸懵逼,就想着自己分析一下,在此记录下来,希望对大家能够有所帮助。...

    砸漏
  • Android编程解析XML文件的方法详解【基于XmlPullParser】

    本文实例讲述了Android编程解析XML文件的方法。分享给大家供大家参考,具体如下:

    砸漏
  • 面试题51(关于抽象类与接口的掌握)

    (单选题)5、A是抽象父类或接口, B , C 派生自 A ,或实现 A ,现在 Java 源代码中有如下声明: 1. A a0=new A(); 2. A...

    Java学习
  • Java中接口和抽象类的区别

    简单来说, 接口是公开的,里面不能有私有的方法或变量,是用于让别人使用的,而抽象类是可以有私有方法或私有变量的,

    ccf19881030
  • SIM Programming On Windows Mobile

          SIM卡在手机中扮演着一个很重要的角色:当手机需要接入蜂窝网络时,需要SIM来进行鉴权,只有授权的用户才能接入网络;当有短信到达时,它可以存储在SI...

    ShiJiong
  • 【Leetcode】107. 二叉树的层次遍历 II

    给定一个二叉树,返回其节点值自底向上的层次遍历。 (即按从叶子节点所在层到根节点所在的层,逐层从左向右遍历)

    Leetcode名企之路
  • go:优雅的退出http服务

    此外,server.ListenAndServe()不能跑在main中,因为在main中,要处理其它任务。如何使main阻塞呢?上段代码done这个协程是能派上...

    超级大猪
  • netperf常用命令参数套餐

    netperf -H 10.18.201.3 -l 60 -- -S 87380 -s 16384 -M 16384 -m 16384

    力哥聊运维与云计算
  • Express.js 4.0 有加入一個新的 Router 功能

    Express.js 4.0 有加入一個新的 Router 功能,它就像一個迷你的應用程式,可以讓應用程式內部的路由撰寫更方便、更有彈性。 Express.js...

    前朝楚水

扫码关注云+社区

领取腾讯云代金券