美文网首页Android自定义View
android text 测量尺寸相关

android text 测量尺寸相关

作者: Zc0716 | 来源:发表于2018-05-13 22:21 被阅读128次

    一、获取推荐的行距

    paint.getFontSpacing()

    即获取推荐的两行文字的baseline之间的距离,这个值是系统根据文字的字体和字号自动计算的。
    作用:手动绘制多行文字时,在需要换行的时候给y坐标加上这个值来下移文字

    canvas.drawText(texts[0],x,y,paint);
    canvas.drawText(texts[1],x,y+paint.getFontSpacing(),paint);
    

    二、获取FontMetrics系列信息

    paint.getFontMetrics()

    FontMetrics主要提供了以下几个文字排印方面的数值:
    ascent、descent、top、bottom、leading
    baseline:文字显示的基线,文字开始绘制的位置
    ascent / descent:限制普通字符的顶部和底部范围,普通字符,上不会高过ascent,下不会低过descent。ascent和descent的值是相对baseline的相对位移,所以ascent的值为负,descent的值为正。
    top / bottom:限制所有字形的顶部和底部范围。除了普通字符,有些字形的显示范围是会超过ascent和descent的限制,但它们都在top和bottom两条线的范围内。类似ascent/descent,top和bottom的值也是相对baseline的相对位移,top值为负,bottom值为正。
    leading:指的是行的额外间距,即相对于上下相邻的两行,上行的bottom和下行的top的距离。
    (ascent和descent的值同时还可以通过paint.ascent()和paint.descent()方法来快捷获取。)

    三、FontMetrics和getFontSpacing()

    从定义可以看出,上图中两行文字的 font spacing (即相邻两行的 baseline 的距离) 可以通过 bottom - top + leading (top 的值为负,前面刚说过,记得吧?)来计算得出。
    但你真的运行一下会发现, bottom - top + leading 的结果是要大于 getFontSpacing() 的返回值的。
    两个方法计算得出的 font spacing 竟然不一样?
    这并不是 bug,而是因为 getFontSpacing() 的结果并不是通过 FontMetrics 的标准值计算出来的,而是另外计算出来的一个值,它能够做到在两行文字不显得拥挤的前提下缩短行距,以此来得到更好的显示效果。所以如果你要对文字手动换行绘制,多数时候应该选取 getFontSpacing() 来得到行距,不但使用更简单,显示效果也会更好。

    四、获取文字的显示范围

    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);
    

    五、测量文字的宽度并返回

    paint.getMeasureText(String text);

    前面有了 getTextBounds(),这里怎么又有一个 measureText()?
    如果你用代码分别使用 getTextBounds() 和 measureText() 来测量文字的宽度,你会发现 measureText() 测出来的宽度总是比 getTextBounds() 大一点点。这是因为这两个方法其实测量的是两个不一样的东西。
    getTextBounds: 它测量的是文字的显示范围(关键词:显示)。形象点来说,你这段文字外放置一个可变的矩形,然后把矩形尽可能地缩小,一直小到这个矩形恰好紧紧包裹住文字,那么这个矩形的范围,就是这段文字的 bounds。
    measureText(): 它测量的是文字绘制时所占用的宽度(关键词:占用)。前面已经讲过,一个文字在界面中,往往需要占用比他的实际显示宽度更多一点的宽度,以此来让文字和文字之间保留一些间距,不会显得过于拥挤。上面的这幅图,我并没有设置 setLetterSpacing() ,这里的 letter spacing 是默认值 0,但你可以看到,图中每两个字母之间都是有空隙的。另外,下方那条用于表示文字宽度的横线,在左边超出了第一个字母 H 一段距离的,在右边也超出了最后一个字母 r(虽然右边这里用肉眼不太容易分辨),而就是两边的这两个「超出」,导致了 measureText() 比 getTextBounds() 测量出的宽度要大一些。

    六、测量字符串每个字符的宽度

    paint.getTextWidths(String text, float[] widths)

    获取字符串中每个字符的宽度,并把结果填入参数 widths。
    这相当于 measureText() 的一个快捷方法,它的计算等价于对字符串中的每个字符分别调用 measureText() ,并把它们的计算结果分别填入 widths 的不同元素。
    getTextWidths() 同样也有好几个变种,使用大同小异,不再介绍。

    相关文章

      网友评论

        本文标题:android text 测量尺寸相关

        本文链接:https://www.haomeiwen.com/subject/pehrdftx.html