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

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

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

相关推荐
祈澈菇凉34 分钟前
如何结合使用thread-loader和cache-loader以获得最佳效果?
前端
垣宇36 分钟前
Vite 和 Webpack 的区别和选择
前端·webpack·node.js
java1234_小锋40 分钟前
一周学会Flask3 Python Web开发-客户端状态信息Cookie以及加密
前端·python·flask·flask3
化作繁星43 分钟前
如何在 React 中测试高阶组件?
前端·javascript·react.js
Au_ust1 小时前
千峰React:函数组件使用(2)
前端·javascript·react.js
爱吃南瓜的北瓜1 小时前
npm install 卡在“sill idealTree buildDeps“
前端·npm·node.js
TTc_1 小时前
记录首次安装远古时代所需的运行环境成功npm install --save-dev node-sass
前端·npm·sass
翻滚吧键盘1 小时前
npm使用了代理,但是代理软件已经关闭导致创建失败
前端·npm·node.js
烂蜻蜓1 小时前
Uniapp 设计思路全分享
前端·css·vue.js·uni-app·html
GAMESLI-GIS1 小时前
【WebGL】fbo双pass案例
前端·javascript·webgl