Flutter 如何从文本小部件中删除不需要的填充?

Flutter how do I remove unwanted padding from Text widget?

我有一个 Text 小部件,虽然我没有在代码中设置任何内容,但我不确定为什么它的顶部和底部似乎只有填充。这是来自默认的 Flutter 应用程序,我只是修改了字体大小。

  body: Center(
    child: Column(
      children: <Widget>[
        Text(
          '0:00.00',
          style: TextStyle(fontSize: 76),
        ),
      ],
    ),
  ),

这是 Android Studio 中突出显示的 Text 小部件的屏幕截图。真的没有别的添加任何填充所以我不知道为什么它在那里。

有时你会在 CSS 中得到这个,即使设置了 none 但你可以简单地用 padding: 0 删除它,但我不知道该怎么做在这里,因为我找不到 Text 小部件的填充选项。

编辑:填充量随字体大小而变化。它似乎总是包含一定数量的填充,例如 html H1 标签。

有两个可能的原因:

  • fontFamily - 试着把它注释掉,看看你是否还有同样的问题。如果这就是原因并且您绝对 must/want 使用此特定字体,我不确定解决方法是什么,除了一些可怕的逻辑来相应地堆叠小部件以使其看起来没有填充。

  • 来自父小部件的布局约束 - 您只包含了文本小部件的代码,但是如果例如它被包裹在列中的扩展小部件中,这也可以解释额外的高度(可能这里的假设是错误的,因为默认情况下文本无论如何都不会垂直居中,但是在层次结构中的某个地方可能会有一个 DefaultTextStyle 小部件,所以仍然可能....)

编辑:文本周围似乎有一些默认填充。

我发现您可以通过设置高度低于 1 的 TextStyle 来减少顶部填充。所需的值似乎取决于字体大小和文本本身,因为不同的字符具有不同的高度。

您还可以通过使用固定大小的容器裁剪文本来减少底部填充。这也会根据字体大小和文本本身而有所不同。下面是使用这两种方法将字体大小为 72 的文本“0:00.00”的顶部和底部填充减少到 0 的示例:

ClipRect(
  child: Container(
    height: 55,
    child: Text("0:00.00",
      style: TextStyle(
        fontSize: 72,
        height: 0.80,
      ),
    ),
  ),
),

我知道这是一个非常糟糕的解决方案,但我不知道有什么更好的解决方案。我尝试在文本小部件上使用自定义 StrutStyle,但这也没有帮助。

Text 小部件有这个 "padding" 是有原因的。考虑下一个例子:

Text(
  '123 gyÓ',
  style: TextStyle(
    fontSize: 40.0,
  ),
),

正如我们所见,使用其他字符(如字母 g 和 y 以及带有重音标记的大写 O)向我们表明 Text 小部件上确实没有填充。

字体在某些字符上有 上升线下降线,还有 上升线对于特殊字符,如 重音标记 。这就是为什么数字居中的原因。这不是 Flutter 方面的填充,而是 排版设计(?)。也许您可以找到一种方法来解决您的问题,方法是寻找一种没有上升和下降的字体。

Wikipedia

上有关字体的更多信息

结论:如果您想 select 使用 Flutter 检查器 Text 小部件,并且在某些字符周围看不到 space,那是不可能的。

尝试通过在样式 属性 中设置高度来调整文本的行高。文本的高度根据字体大小确定。它将乘以字体大小并为您提供 space 看起来像是有一些填充。文本的行高也与字体本身有关,因为每种字体都有自己的行高。

child: Text(
        'Some text goes here',
        style: TextStyle(
          fontSize: 25.0,
          height: 1,
       ),
      )

最终我自己找到了解决方案。它可以使用 StackRow 小部件进行定位。我发现 Row 比使用 Positioned 效果更好,因为文本可以使用 Row 小部件居中。

  body: Stack(
    children: <Widget>[
      Row(
        mainAxisAlignment: MainAxisAlignment.center,
        children: <Widget>[
          Text(
            '0:00.00',
            style: TextStyle(fontSize: 76),
          ),
        ],
      ),
      Padding(
        padding: EdgeInsets.only(top: 56.0),
        child: Row(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text(
              'Coke',
              style: TextStyle(fontSize: 76),
            ),
          ],
        ),
      ),
    ],
  )

它有点像 CSS 中的负填充,但实际上它是将底部文本向下而不是向上移动的填充,否则它们占据相同的 space.

我想我找到了一个很好的 solution/workaround 来删除顶部和底部填充。

诀窍是将您的文本放入容器中,然后在 Text 内更改 TextStyleheight 以及 Container 的高度].为了获得完美的测量结果有点来回走动,但我认为这是值得的。

这是我自己的代码中的示例。

Container(
  height: 24,
  child: Text(
    'Auto',
    style: TextStyle(
      height: 0.77,
      fontSize: 32,
      fontWeight: FontWeight.bold,
      color: Colors.white,
    ),
    textAlign: TextAlign.center,
),

谷歌搜索了一段时间后,我写了这个。 它有什么作用?它正在向下移动文本的位置 (不收缩)

import 'package:vector_math/vector_math_64.dart';
import 'package:flutter/material.dart';

class BaselineText extends StatefulWidget {
  final Widget child;
  BaselineText({this.child});

  @override
  _BaselineTextState createState() => _BaselineTextState();
}

class _BaselineTextState extends State<BaselineText> {
  GlobalKey _key = GlobalKey();

  void initState() {
    super.initState();
    WidgetsBinding.instance.addPostFrameCallback((_) => setState(() {}));
  }

  @override
  Widget build(BuildContext context) {
    final RenderBox renderBox = _key.currentContext?.findRenderObject();
    final height = renderBox?.size?.height ?? 0;
    return Baseline(
      baseline: 0,
      baselineType: TextBaseline.ideographic,
      key: _key,
      child: Transform(
        transform: Matrix4.translation(
          Vector3(0, height, 0),
        ),
        child: widget.child,
      ),
    );
  }
}

使用方法:

BaselineText(
   child: Text("something"),
)

完成!!!

去除不需要的填充的正确方法是在 TextStyle 中设置 height 属性。这样你就可以设置每行的高度。

                  Text(
                    "Let's make\nsome pancakes",
                    style: TextStyle(
                      height: 1.2, //SETTING THIS CAN SOLVE YOUR PROBLEM
                      color: Colors.white,
                      fontSize: 20,
                      fontWeight: FontWeight.w300,
                    ),
                    textAlign: TextAlign.center,
                  ),

事实上,我们可以从文档中确认:

For most fonts, setting height to 1.0 is not the same as omitting or setting height to null because the fontSize sets the height of the EM-square, which is different than the font provided metrics for line height.

更多信息:https://api.flutter.dev/flutter/painting/TextStyle/height.html

所以试一试。它对我有用。