Android TextView一些常用概念解析

  • 现代 Android 中的 leading

    • 通常为0 ,因为行间距由 lineSpacingMultiplierlineSpacingExtra 属性管理。
    • 不再依赖于 Paint.FontMetrics 中的 leading 来调整行间距。
  • 行间距管理

    • 优先使用 lineSpacingMultiplierlineSpacingExtra 来调整行间距。
    • 结合两者使用 可以实现灵活且精确的行间距控制。
    • 高级控制 :通过自定义 LineHeightSpan 或其他高级方法,可以实现更细粒度的行高管理。
  • 设计和可读性

    • 适当的行间距 提高文本的可读性和整体界面的美观性。
    • 根据字体和文本大小 调整行间距,确保在各种设备和配置下的最佳显示效果。

通过理解现代 Android 中行间距的管理方式,以及合理应用相关属性,您可以在 TextView 中实现理想的文本布局,提升用户的阅读体验和界面美感。

js 复制代码
+--------------------------+
|          Top             |
|                          |
|  Ascent                  |
|    _________             |
|   |         |            |
|   |  Text   |            |  <-- Baseline of Line 1
|   |         |            |
|   |_________|            |
|     Descent              |
|                          |
|      Leading Space       |  <-- Space between Baselines
|                          |
|    _________             |
|   |         |            |
|   |  Text   |            |  <-- Baseline of Line 2
|   |         |            |
|   |_________|            |
|     Descent              |
|                          |
|         Bottom           |
+--------------------------+
  • baseline:水平方向的一条线,字符通常以此为参考对齐,绝大多数字符"脚"都在这条线上。

  • ascent:从 baseline 往上到字符最高处的距离(多为负值)。

  • descent:从 baseline 往下到字符最低处的距离(通常为正值)。

  • top :字符最顶端可能达到的距离(通常比 ascent 更"高"一点,负值更大)。

  • bottom :字符最底端可能达到的距离(通常比 descent 更"低"一点,正值更大)。

在 Android 中,如果要获取单行文本的上述度量,可以通过 TextViewPaint 对象或直接使用 Paint 本身:

js 复制代码
TextView textView = findViewById(R.id.your_text_view);

// 1. 获取 Paint 对象
Paint paint = textView.getPaint();

// 2. 获取 FontMetrics
Paint.FontMetrics fontMetrics = paint.getFontMetrics();

// 3. 取出 top, ascent, descent, bottom, baseline(baseline 通常以 0 参考值呈现)
float topValue = fontMetrics.top;
float ascentValue = fontMetrics.ascent;
float descentValue = fontMetrics.descent;
float bottomValue = fontMetrics.bottom;
float leadingValue = fontMetrics.leading;  // leading 在现代安卓中经常为0

行间距的计算

TextView 中,行间距(行高)的计算主要基于以下几个因素:

  1. 字体的 ascentdescent
  2. 行间距属性 lineSpacingExtralineSpacingMultiplier

计算公式如下:

js 复制代码
行高 = ( |ascent| + descent ) * lineSpacingMultiplier + lineSpacingExtra
  • 获取纯文本的显示区域坐标
js 复制代码
paint.getTextBounds("afyq", 0, "abab".length, bounds)

bounds返回的就是左上右下,如果你想实现文字完全贴边,可以考虑这种方式,下图中的af完全贴近屏幕了。

  • 如何让文本完全居中: 在代码中,如果我们只设置宽高的二分之一,这只是代表了文本的基线是居中的,文字整体显示其实并不居中,要想让整个都居中,我们需要对基线做偏移,因为文本的绘制都是以基线为基准进行的:
js 复制代码
canvas.drawText("afyq", width / 2f, height / 2f, paint)

将上边的代码修改为:

js 复制代码
canvas.drawText("afyq", width / 2f, height / 2f - (fontMetrics.ascent + fontMetrics.descent) / 2f, paint)

对于同一种字体,它的ascent和descent是固定的,因此通过对基线做上边的偏移,就可以实现完全居中了,需要注意ascent是负值,而descent是正值,因此上边的height / 2f 减去的是一个负数,因此才能保证基线是向下偏移的。

上边就是偏移基线之后一个完全居中的文本。不做偏移,看到的就是这个效果:

两者对比情况显而易见了。

相关推荐
裁二尺秋风25 分钟前
Nginx — Nginx处理Web请求机制解析
前端·nginx
excel29 分钟前
webpack 核心编译器 第五节
前端
曲辒净1 小时前
vue搭建一个树形菜单项目
前端·javascript·vue.js
喝拿铁写前端7 小时前
前端与 AI 结合的 10 个可能路径图谱
前端·人工智能
codingandsleeping7 小时前
浏览器的缓存机制
前端·后端
灵感__idea9 小时前
JavaScript高级程序设计(第5版):扎实的基本功是唯一捷径
前端·javascript·程序员
摇滚侠9 小时前
Vue3 其它API toRow和markRow
前端·javascript
難釋懷9 小时前
JavaScript基础-history 对象
开发语言·前端·javascript
beibeibeiooo9 小时前
【CSS3】04-标准流 + 浮动 + flex布局
前端·html·css3