【问题标题】:Flutter how do I remove unwanted padding from Text widget?Flutter 如何从 Text 小部件中删除不需要的填充?
【发布时间】:2019-11-22 07:56:40
【问题描述】:

我有一个Text 小部件,不知道为什么它似乎只是在顶部和底部有填充,即使我没有在代码中设置任何内容。这是默认的 Flutter 应用,我只是修改了字体大小。

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

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

有时你会在 CSS 中得到它,即使没有设置任何填充,但你可以简单地使用 padding: 0 将其删除,但我不知道如何在此处执行,因为我找不到填充选项Text 小部件。

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

【问题讨论】:

  • 我认为更多的代码包括某种容器或整个代码。
  • @yaho cho 这是文本小部件的完整代码,它是在 Android Studio 的图像中突出显示的小部件。没有其他任何东西可以影响它。它只是保存在一个没有参数的children: &lt;widget&gt;[ 中,也就是一个没有参数的Row
  • 你试过负填充吗?
  • @dmarquina 我没有尝试过任何类型的填充,因为我不知道 Text 小部件有填充设置。那你怎么设置呢?
  • 我将问题修改为默认的 Flutter 应用程序以提高透明度。即使在那里,您也可以看到问题存在。您当然可以使用默认项目在 Flutter 中自己重新创建问题。

标签: flutter dart padding


【解决方案1】:

消除不需要的填充的正确方法是在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,
                  ),

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

对于大多数字体,将 height 设置为 1.0 与忽略或将 height 设置为 null 不同,因为 fontSize 设置了 EM-square 的高度,这与字体提供的行高指标不同。

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

那就试一试吧。它对我有用。

【讨论】:

  • 这对我有用!我认为最好的解决方案。
【解决方案2】:

Text 小部件具有这种“填充”是有原因的。考虑下一个例子:

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

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

字体在某些字符上有 ascendersdescenders,并且还有 en ascent line 用于特殊字符,例如 accent marker。这就是为什么数字居中的原因。这不是 Flutter 方面的填充,而是排版设计(?)。也许你可以找到一种方法来解决你的问题,寻找一种没有升序和降序的字体。

更多关于字体的信息Wikipedia

结论:如果你想用 Flutter 检查器选择 Text 小部件,并且看到某些字符周围没有空格,那是不可能的。

【讨论】:

  • 是的,请参阅上面的上划线装饰。您也可以尝试使用 h、d 等字符。正如您在我提供的 Wikipedia 链接上看到的那样,这些字符具有升序。不要认为反对票是公平的。 :(
  • 检查我的问题中的屏幕截图。零是所有角色中最高的,但在它们上方仍有很大的空间。没有理由在这个级别高于...没有一个角色能达到那么高。
  • 你是对的。对不起,那是所谓的上升线。您可以尝试在大写字符上加上重音符号,例如 Ó。无论如何我都会更新我的答案。
  • @Hasen 请检查我更新的答案。感谢您指出我的遗漏。 :)
  • 您对较低的填充是正确的,尽管确实需要一种解决方法。例如,在大写字母中拥有一个标题必须在它下面有一个很大的差距......这是非常有限的。没有办法解决吗?在 React Native 中,我们可以使用从负填充到绝对定位的任何方法来解决这个问题……一定是颤振的方法吗?我对它很陌生,所以不知道。
【解决方案3】:

我想我找到了一个很好的解决方案/解决方法来删除顶部和底部填充。

诀窍是将您的文本放入容器中,然后更改文本内的 TextStyle 的“高度”,以及容器的高度。为了完美的测量需要来回走动,但这是值得的。

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

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

【讨论】:

  • 它对我有用。谢谢
【解决方案4】:

有两个可能的原因:

  • fontFamily - 尝试将其注释掉,看看您是否还有同样的问题。如果这是原因并且您绝对必须/想要使用这种特定字体,我不确定修复是什么,除了一些可怕的逻辑来相应地堆叠小部件以使其看起来没有填充。

  • 来自父 Widget 的布局约束 - 您只包含 Text 小部件的代码,但如果它包含在 Column 内的 Expanded 小部件中,这也可以解释额外的高度(这里可能是错误的假设,因为无论如何,文本默认不会垂直居中,但是在层次结构中可能会有一个 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,
      ),
    ),
  ),
),

我知道这是一个非常糟糕的解决方案,但我不知道有更好的解决方案。我尝试在 Text 小部件上使用自定义 StrutStyle,但这也无济于事。

【讨论】:

  • 我尝试注释掉字体系列,但它没有改变任何东西。它只是保存在children: &lt;widget&gt;[ 中,根本没有参数,而Row 也没有参数。 Android Studio 的检查器显示它是具有该填充的文本小部件,如您在上面的屏幕截图中所见。
  • 似乎有一些关于颤振中这种“默认填充”的帖子,但不是关于文本小部件的,所以我无法采用他们的解决方案。至少,这似乎是 Flutter 中的一个常见问题。
  • 我将问题修改为默认的 Flutter 应用程序以提高透明度。即使在那里,您也可以看到问题存在。您当然可以使用默认项目在 Flutter 中自己重新创建问题。
  • 这似乎只是摆脱了顶部的填充。这很奇怪。没有大写的大写字母,下面没有巨大的空白,就没有办法。
  • 向 TextStyle 添加 'height: 1' 为我解决了这个问题。
【解决方案5】:

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

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

【讨论】:

  • 这是在其他答案之一中提出的,但就像我在那里评论的那样,它不会删除底部的填充,只删除顶部的填充。想象一下,如果您在此文本小部件下方有一个Container,您将如何缩小它们之间的差距?
  • 帮助我摆脱顶部填充
【解决方案6】:

最后我自己找到了解决方案。它可以使用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 中的负填充,但实际上它是向下移动底部文本而不是向上移动的填充,否则它们会占用相同的空间。

【讨论】:

  • 使用此解决方案,您没有删除问题中提出的额外填充。您刚刚重叠了两个小部件。所以这不能是你主要问题的答案
  • 这无法解决。
【解决方案7】:

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

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"),
)

完成!!!

【讨论】:

  • 不编译:A value of type 'RenderObject?' can't be assigned to a variable of type 'RenderBox'. Try changing the type of the variable, or casting the right-hand type to 'RenderBox'.
猜你喜欢
  • 1970-01-01
  • 2022-08-23
  • 2022-07-30
  • 2021-02-18
  • 1970-01-01
  • 2011-04-07
  • 1970-01-01
  • 2014-03-12
  • 2020-11-08
相关资源
最近更新 更多