Flutter Text 行高相关

Posted 一叶飘舟

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Flutter Text 行高相关相关的知识,希望对你有一定的参考价值。

前言

TextFlutter最常见的Widget之一。我们可以用它放置文本,或者在默认组件不满足要求的情况下,可以结合其他组件来组成如按钮这些的自定组件

虽然用法很简单,但不注意的情况下依旧会出现很多奇奇怪怪的问题。下面就总结下行高部分遇到的问题和解决方案。

height 行高问题

若是设计是按web来给的Flutter布局属性,那通常来说都会有个height属性,但这时候我们就要根据情况来决定是否要设置这个height,不能原样照抄。

为什么?因为Textheightnull的情况下,即不设置行高的情况下,文本是默认在框的垂直居中位置的,并且会自适应大小。

而若是设置了height之后,则空间分布的策略则不会是均匀分布了。文字上方和下方的总空间叫leading

When [height] is provided, the line's EM-square ascent and descent (which sums to [fontSize]) will be scaled by [height] to achieve a final strut height of fontSize * height + fontSize * leading logical pixels. The following diagram illustrates the differences between the font metrics defined height and the EM-square height:

proportional → const TextLeadingDistribution

Distributes the leading of the text proportionally above and below the text, to the font's ascent/descent ratio.

The leading of a text run is defined as TextStyle.height * TextStyle.fontSize - TextStyle.fontSize. When TextStyle.height is not set, the text run uses the leading specified by the font instead.

所以设置height之后,则会按比例分布leading在文本的上方和下方。具体这个比例根据字体而定。

(图片来自Flutter)

所以如果我们绘制的是一个如按钮类的少量单行的文本,这时候我们就最好不要设置height,让系统自动处理来居中(默认字体下)。然后英文比如g之类的看起来不居中,这个跟基线有关,实际对于英文来说就是居中的。

当然,我们也可以设置策略为均匀分布的,

Text(
  "测试Test 2.0",
  style: TextStyle(
    fontSize: 15,
    height: 2.0,
    leadingDistribution: TextLeadingDistribution.even, // 设置leading策略
  ),
)

TextLeadingDistribution有两个,proportionaleven,默认为proportional,根据字体的leading比例来分布上下空间。even则是均分上下空间,就是CSS中的"half-leading"

看看效果

即使height为2.0,可以看到也是居中的,不过上下空间相应增大。1.0的未处理。

如何实现首字下沉效果

height其实是最外层简单的属性。他实际设置的是StrutStyle中的heightStrutStyle可以设置总的行的空间样式(下面称为支柱样式),即简单来说,TextRich可以用它来指定一个行的总支柱,并且各个TextSpan依旧可以设定自己的TextStyle,但不会影响到支柱。

直接看官方的示例

const Text.rich(
  TextSpan(
    text: '       he candle flickered\\n',
    style: TextStyle(
      fontSize: 14,
      fontFamily: 'Serif'
    ),
    children: <TextSpan>[
      TextSpan(
        text: 'T',
        style: TextStyle(
          fontSize: 37,
          fontFamily: 'Serif'
        ),
      ),
      TextSpan(
        text: 'in the moonlight as\\n',
        style: TextStyle(
          fontSize: 14,
          fontFamily: 'Serif'
        ),
      ),
      TextSpan(
        text: 'Dash the bird fluttered\\n',
        style: TextStyle(
          fontSize: 14,
          fontFamily: 'Serif'
        ),
      ),
      TextSpan(
        text: 'off into the distance.',
        style: TextStyle(
          fontSize: 14,
          fontFamily: 'Serif'
         ),
      ),
     ],
   ),
   strutStyle: StrutStyle(
     fontFamily: 'Serif',
     fontSize: 14,
     forceStrutHeight: true,
   ),
)

实际上T是在第二行,但该行的支柱并没有因为他的fontSize而撑大,因为StrutStyle已经定义好了每行的支柱

首字下沉的方式很简单的就实现了。

总结

设置height即在设置文本的支柱高度,这个高度是文本高度和文本上下的空间leading)之和。在不设置的情况下,会自动均匀分配leading。所以要根据设计图的情况,分析是否需要设置height,单行文本居中的话,一般都不需要设置,除非需要根据文本大小来规定高度,那么就配合TextLeadingDistribution.even来设置leading分配的策略;若是多行文案的布局(文章类展示),则可以设置height来达到一个更好的视觉效果。

height不能够满足要求的情况下,可以配置StrutStyle来更高级的设置支柱和文本的搭配,实现更好的效果。

以上是关于Flutter Text 行高相关的主要内容,如果未能解决你的问题,请参考以下文章

Flutter Web 行高不一致

首字下沉

text 更改自定义模板的行高

如何使用 Pango 在 Clutter.Text 中设置行高

Flutter:在 Text Widget 中添加新行

lable计算行高