我的自定义View学习笔记(三)—— drawText() 文字的绘制

  • 这个一个系列,本系列讲的都是本人自定义 View 的学习笔记。目的是加深影响,便于在以后工作中遇到相关问题的时候,能够有个印象知道到哪里去寻找答案。
  • 这是我学习扔物线大神的自定义 View 教程,自己记录的笔记。链接在这里HenCoder,强烈推荐大家去原地址学习,毕竟我写的笔记只是针对我个人的口味而言的,用词和对概念的理解不一定有扔物线大神准确。
  • 我再发一次地址:https://hencoder.com

一、Canvas 绘制文字

1、drawText(String text, float x, float y, Paint paint)

  • text 为需要绘制的文字
  • x 为文字绘制的最左边的坐标(实际位置还要再靠左一点,考虑到文字的间距)
  • y 为文字绘制的最下面的坐标(区别于绘制其他图形时,以左上角为起点的方式。这是为了文字的美观,重心对齐的方式)
  • paint 画笔

2、drawTextRun()

  • 对汉字和英文没有,貌似适用于阿拉伯语那种歪歪扭扭的字体

3、drawTextOnPath(String text, Path path, float hOffset, float vOffset, Paint paint)

  • 沿着一条 Path 来绘制文字
  • text 为所需要绘制的文字
  • path 为文字的路径
  • hOffset 文字相对于路径的水平偏移量,用于调整文字的位置
  • vOffset 文字相对于路径竖直偏移量,用于调整文字的位置
  • 值得注意的是,在绘制 Path 的时候,应该在拐弯处使用圆角,这样文字显示时更舒服

4、StaticLayout(CharSequence source, TextPaint paint, int width, LayoutAlignment align, float spacingmult, float spacingadd, boolean includepad)

  • drawText 方法,不会给文字换行,如果想实现换行需要自己去计算换行的时机
  • StaticLayout 不是一个 View 或者 ViewGroup,而是 Layout 的子类是纯粹用来绘制文字的,支持换行:
    • 为文字设置宽度上线,实现自动换行
    • 使用换行符 \n,主动换行
  • 该方法参数解析:
    • width 文字区域的宽度,文字达到这个宽度后就换行
    • align 文字对齐方向
    • spacingmult 行间距倍数,通常填1
    • spacingadd 行间距的额外增加值,通常填0
    • includeadd 是否在文字上下添加额外的空间,避免某些过高的字符的绘制出现越界

二、Paint 对文字绘制的辅助

1、设置显示效果类

  • setTextSize()
    • 设置文字大小
  • setTypeface()
    • 设置字体
    • 默认的只有粗体、斜体
  • setFakeBoldText(boolean fakeBoldText)
    • 是否使用伪粗体
    • 伪粗体:不是选用更高 weight 的字体让文字变粗,而是通过程序在运行时把文字“描粗”
  • setStrikeThruText(boolean strikeThruText)
    • 是否加删除线
  • setUnderlineText(boolean underlineText)
    • 是否加下划线
  • setTextSkewX(float skewX)
    • 文字横向错切角度,即文字斜度
  • setTextScaleX(float scaleX)
    • 设置文字横向放缩,即文字胖瘦
  • setTextLetterSpacing(float letterSpacing)
    • 设置字符间距,默认为0
  • setFontFeatureSettings(String settings)
    • 用 CSS 的 font-feature-settings 的方式来设置文字
  • setTextAlign(Paint.Align align)
    • 文字对齐方式,一共有三个值:LEFT CETNER 和 RIGHT,默认值为 LEFT
  • setTextLocale(Locale locale) / setTextLocales(LocaleList locales)
    • 在不改变系统语言的情况下,设置语言地域

2、测量文字尺寸类

  • float getFontSpacing()

    • 获取推荐的行距
    • 作用是当你要手动绘制多行文字的时候,可以在换行的时候给 y 坐标加上这个值来下移文字
  • FontMetircs getFontMetrics()

    • 获取 Paint 的 FontMetrics
    • FontMetrics 是一个专业的工具类,提供文字排印方面的数值
      image
    • baseline: 上图中黑色的线,它的作用是作为文字显示的基准线
    • ascent / descent:上图中绿色和橙色的线,它们的作用是限制普通字符的顶部和底部范围。普通的字符,上不会高过 ascent ,下不会低过 descent
      • ascent 的值是图中绿线和 baseline 的相对位移,它的值为负(因为它在 baseline 的上方)
      • descent 的值是图中橙线和 baseline 相对位移,值为正(因为它在 baseline 的下方)。
    • top / bottom: 上图中蓝色和红色的线,它们的作用是限制所有字形( glyph )的顶部和底部范围。除了普通字符,有些字形的显示范围是会超过 ascent 和 descent 的,而 top 和 bottom 则限制的是所有字形的显示范围,包括这些特殊字形
      • top 的值是图中蓝线和 baseline 的相对位移,它的值为负(因为它在 baseline 的上方)
      • bottom 的值是图中红线和 baseline 相对位移,值为正(因为它在 baseline 的下方)
    • leading:leading 指的是行的额外间距,即对于上下相邻的两行,上行的 bottom 线和下行的 top 线的距离,也就是上图中第一行的红线和第二行的蓝线的距离(对,就是那个小细缝)
    • 有需要时再具体看吧,挺麻烦的
  • getTextBounds(String text, int start, int end, Rect bounds)

    • 获取文字的显示范围
    • text 是需要测算的问题
    • start、end 是文字的起始和结束位置
    • bounds 是存储文字的显示范围对象
paint.setStyle(Paint.Style.FILL);  
canvas.drawText(text, offsetX, offsetY, paint);

paint.getTextBounds(text, 0, text.length(), bounds);  
bounds.left += offsetX;  
bounds.top += offsetY;  
bounds.right += offsetX;  
bounds.bottom += offsetY;  
paint.setStyle(Paint.Style.STROKE);  
canvas.drawRect(bounds, paint);  
  • float measureText(String text)

    • 测量文字宽度
    • getTextBounds() 和 measureText() 的区别
      • getTextBounds: 它测量的是文字的显示范围(关键词:显示)
      • measureText(): 它测量的是文字绘制时所占用的宽度(关键词:占用)
      • 一个文字在界面中,往往需要占用比他的实际显示宽度更多一点的宽度,以此来让文字和文字之间保留一些间距,不会显得过于拥挤。所以measureText()测出来的宽度总是比 getTextBounds() 大一点点
  • getTextWidths(String text, float[] widths)

    • 获取字符串中每个字符的宽度,并把结果填入参数 widths
  • int breakText(String text, boolean measureForwards, float maxWidth, float[] measuredWidth)

    • 这个方法也是用来测量文字宽度的。但和 measureText() 的区别是, breakText() 是在给出宽度上限的前提下测量文字的宽度。如果文字的宽度超出了上限,那么在临近超限的位置截断文字
    • 用于多行文字的折行计算
  • 光标相关

    • getRunAdvance(CharSequence text, int start, int end, int contextStart, int contextEnd, boolean isRtl, int offset)
      • 计算光标的某个位置
    • 还有一个计算方法
  • hasGlyph(String string)

    • 检查指定的字符串中,是否是一个单独的字形
    • image

猜你喜欢

转载自blog.csdn.net/Android_03/article/details/84072749
今日推荐