Android自定义View(三) -- drawText()

本文深入探讨Android自定义View中drawText()的使用,包括drawText()、drawTextRun()、drawTextOnPath()等方法。重点介绍了drawText()的坐标原理和StaticLayout的使用。同时,详细解析了Paint对象在文字绘制过程中的辅助作用,如设置文字大小、字体、样式等,并讲解了测量文字尺寸的相关方法。
摘要由CSDN通过智能技术生成

前面学习了
Android自定义View(一) – 初识
Android自定义View(二) – Paint详解

今天继续学习第三篇内容drawText(),本文是对第二篇文章中drawText的拓展,进行详细学习


本文计划根据HenCoder系列文章进行学习,所以代码风格及博文素材可能会摘自其中。


1.Canvas 绘制文字的方式

Canvas 的文字绘制方法有三个:drawText() drawTextRun() 和 drawTextOnPath()。

1.1 drawText(String text, float x, float y, Paint paint)

drawText() 是 Canvas 最基本的绘制文字的方法:给出文字的内容和位置, Canvas 按要求去绘制文字。

        paint = new Paint();
        paint.setColor(Color.GRAY);
        paint.setStyle(Paint.Style.STROKE);
        paint.setStrokeWidth(5);
        paint.setTextSize(200);
        .
        if (paint == null || TextUtils.isEmpty(this.charSequence)){
            return;
        }
        canvas.drawText(charSequence.toString(),20,200,paint);

drawText

方法的参数很简单: text 是文字内容,x 和 y 是文字的坐标。但需要注意:这个坐标并不是文字的左上角,而是一个与左下角比较接近的位置。大概在这里:

x.y坐标

如果像绘制其他内容一样,设置(0,0),文字不会显示在屏幕左上角,直接显示在屏幕外,无法观察到。

附上一张图,应该能更清楚地表达:

image

这是为什么?为什么其它的 Canvas.drawXXX() 方法,都是以左上角作为基准点的,而 drawText() 却是文字左下方?

先别觉得日了狗,这种设计其实是有道理的。drawText() 参数中的 y ,指的是文字的基线( baseline ) 的位置。也就是这条线:

image

众所周知,不同的语言和文字,每个字符的高度和上下位置都是不一样的。要让不同的文字并排显示的时候整体看起来稳当,需要让它们上下对齐。但这个对齐的方式,不能是简单的「底部对齐」或「顶部对齐」或「中间对齐」,而应该是一种类似于「重心对齐」的方式。就像电线上的小鸟一样:

image

每只小鸟的最高点和最低点都不一样,但画面很平衡

而这个用来让所有文字互相对齐的基准线,就是基线( baseline )。 drawText() 方法参数中的 y 值,就是指定的基线的位置。

说完 y 值,再说说 x 值。从前面图中的标记可以看出来,「Hello HenCoder」绘制出来之后的 x 点并不是字母 “H” 左边的位置,而是比它的左边再往左一点点。那么这个「往左的一点点」是什么呢?

它是字母 “H” 的左边的空隙。绝大多数的字符,它们的宽度都是要略微大于实际显示的宽度的。字符的左右两边会留出一部分空隙,用于文字之间的间隔,以及文字和边框的间隔。就像这样:

image

用竖线标记出边界后的文字。

所以,明白为什么 x 坐标在 “H” 的左边再往左一点点的位置,而不是紧贴着 “H” 的左边线了吗?就是因为 “H” 的这个留出的空隙。

除了 drawText(text, x, y, paint) 之外, drawText() 还有几个重载方法,使用方式跟这个都差不多。

1.2 drawTextRun()

这部分对中英文没有作用,对一些特殊文字有作用,如果需要了解,参考原文中讲解HenCoder-drawText

1.3 drawTextOnPath()

沿着一条 Path 来绘制文字。这是一个耍杂技的方法。

path.addRect(200,300,600,800,Path.Direction.CW);
 canvas.drawTextOnPath(charSequence.toString(),path,0,0,paint);

image.png

drawTextOnPath(String text, Path path, float hOffset, float vOffset, Paint paint)
参数里,需要解释的只有两个: hOffset 和 vOffset。它们是文字相对于 Path 的水平偏移量和竖直偏移量,利用它们可以调整文字的位置。例如你设置 hOffset 为 5, vOffset 为 10,文字就会右移 5 像素和下移 10 像素。

1.4 StaticLayout

额外讲一个 StaticLayout。这个也是使用 Canvas 来进行文字的绘制,不过并不是使用 Canvas 的方法。

Canvas.drawText() 只能绘制单行的文字,而不能换行。它:

  • 不能在 View 的边缘自动折行
  String text = "Lorem Ipsum is simply dummy text of the printing and typesetting industry.";
  ...
  canvas.drawText(text, 50, 100, paint);

image

到了 View 的边缘处,文字继续向后绘制到看不见的地方,而不是自动换行

  • 不能在换行符 \n 处换行
  String text = "a\nbc\ndefghi\njklm\nnopqrst\nuvwx\nyz";
  ...
  canvas.drawText(text, 50, 100, paint);

image

在换行符 \n 的位置并没有换行,而只是加了个空格

如果需要绘制多行的文字,你必须自行把文字切断后分多次使用 drawText() 来绘制,或者——使用 StaticLayout 。

StaticLayout 并不是一个 View 或者 ViewGroup ,而是 android.text.Layout的子类,它是纯粹用来绘制文字的。 StaticLayout 支持换行,它既可以为文字设置宽度上限来让文字自动换行,也会在 \n 处主动换行。
image.png

StaticLayout 的构造方法是 StaticLayout(CharSequence source, TextPaint paint, int width, Layout.Alignment align, float spacingmult, float spacingadd, boolean includepad),其中参数里:

width 是文字区域的宽度,文字到达这个宽度后就会自动换行;
align 是文字的对齐方向;
spacingmult 是行间距的倍数,通常情况下填 1 就好;
spacingadd 是行间距的额外增加值,通常情况下填 0 就好;
includeadd 是指是否在文字上下添加额外的空间,来避免某些过高的字符的绘制出现越界。

如果你需要进行多行文字的绘制,并且对文字的排列和样式没有太复杂的花式要求,那么使用 StaticLayout 就好。

2 Paint 对文字绘制的辅助

Paint 对文字绘制的辅助,有两类方法:设置显示效果的和测量文字尺寸的。

2.1 设置显示效果类

2.1.1 setTextSize(float textSize)

设置文字大小。

paint.setTextSize<
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值