TextView 在布局方面提供了一些特别的属性来控制文本的布局。比如现在要显示一个句子 What is a good time for you?。 TextView 在发现一行布局不足以显示整个文本内容时,会进行自动的换行。
那么 TextView 是如何知道或者说它是如何做到自动换行的呢? 这就要涉及下图所示的内容。
Layout
官方介绍: android.text.Layout 是一个管理屏幕上文本布局的基类。在 TextView 内部,对于会编辑的文本(EditText),会使用 DynamicLayout ,它会随着文本的更改而更新;对于不会更改的文本,会使用 StaticLayout 或 BroingLayout。
getLineXXX
由于文本可能会被显示为多行,所以 Layout 提供了一系列获取每一行文本具体位置的方法。通过 getLineCount()
可以获取一个 Layout 包含了多少行文本,然后通过一系列 getLineXXX(int line)
方法可以获取每行的具体参数。
- getLineTop: 当前行文本区域的最顶部在屏幕y方向的位置
- getLineBottom: 当前行文本区域的最底部在屏幕y方向的位置, 会包含实际的行间距X(最后一行不会包含)
- getLineBaseline:
- getLineStart: 绘制在当前行的第一个字符在所有字符中的索引
- getLineEnd: 绘制在当前行的最后一个字符在所有字符中的索引
- getLineLeft: 绘制在当前行的第一个字符在屏幕x方向的位置
- getLineRight: 绘制在当前行的最后一个字符在屏幕x方向的位置
- getLineAscent: 获取字体头部的额外高度,相对于 Bottom 的偏移
- getLineDescent: 获取字体底部相对于 Bottom 的偏移
- …
自己尝试画这些线:
repeat(layout.lineCount) {
drawLine(canvas, Color.RED, layout.getLineTop(it), "top")
drawLine(canvas, Color.YELLOW, layout.getLineAscent(it) + layout.getLineBottom(it), "ascent")
drawLine(canvas, Color.BLUE, layout.getLineBaseline(it), "baseline")
drawLine(canvas, Color.GREEN, layout.getLineBottom(it), "bottom")
drawLine(canvas, Color.BLACK, layout.getLineDescent(it) + layout.getLineBottom(it), "descent")
}
单行 | 多行 |
---|---|
FontMetricsInt
与文本布局有关的还有一个数据类,FontMetricsInt,它封装了一系列字体相对与 baseline
的偏移量。
public static class FontMetricsInt {
/**
* The maximum distance above the baseline for the tallest glyph in
* the font at a given text size.
*/
public int top;
/**
* The recommended distance above the baseline for singled spaced text.
*/
public int ascent;
/**
* The recommended distance below the baseline for singled spaced text.
*/
public int descent;
/**
* The maximum distance below the baseline for the lowest glyph in
* the font at a given text size.
*/
public int bottom;
/**
* The recommended additional space to add between lines of text.
*/
public