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 减去的是一个负数,因此才能保证基线是向下偏移的。

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

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

相关推荐
一城烟雨_1 小时前
vue3 实现将html内容导出为图片、pdf和word
前端·javascript·vue.js·pdf
树懒的梦想2 小时前
调整vscode的插件安装位置
前端·cursor
低代码布道师3 小时前
第二部分:网页的妆容 —— CSS(下)
前端·css
一纸忘忧3 小时前
成立一周年!开源的本土化中文文档知识库
前端·javascript·github
涵信4 小时前
第九节:性能优化高频题-首屏加载优化策略
前端·vue.js·性能优化
前端小巷子4 小时前
CSS单位完全指南
前端·css
SunTecTec5 小时前
Flink Docker Application Mode 命令解析 - 修改命令以启用 Web UI
大数据·前端·docker·flink
拉不动的猪6 小时前
前端常见数组分析
前端·javascript·面试
小吕学编程6 小时前
ES练习册
java·前端·elasticsearch
Asthenia04126 小时前
Netty编解码器详解与实战
前端