如何防止多行文本小部件放置在行中时被剪裁?

Posted

技术标签:

【中文标题】如何防止多行文本小部件放置在行中时被剪裁?【英文标题】:How can I prevent a multi-line Text widget from getting clipped when placed within a Row? 【发布时间】:2017-06-03 07:28:48 【问题描述】:

我的 Flutter 应用中有一个 Text 小部件,其中包含一个长文本字符串。它被放置在具有固定宽度的 Container 中。默认情况下,文本字符串换行为多行。

但是,当我尝试将该 Text 小部件插入 Row 小部件时,文本字符串突然切换为单行,并在右侧被剪裁。

当 Text 小部件位于 Row 中时,保持其原始多行行为的简单方法是什么?

这是我一直在使用的代码:

var container = new Container (
  child: new Row (
    children: [
      new Icon (Icons.navigate_before),
      new Text ("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat."),
      new Icon (Icons.navigate_next),
    ],
  ),
  decoration: new BoxDecoration (
    backgroundColor: Colors.grey[300],
  ),
  width: 400.0,
);

【问题讨论】:

【参考方案1】:

要知道的最重要的事情是,列或行中的子小部件会占用它们所需的空间默认情况下

子元素本身不受行/列的主轴大小(宽度/高度)的限制,如果它们更大会溢出。 (因此,为什么你会看到右侧的红色溢出指示器)

您的行为不是由于文本小部件,而是由于布局本身。您需要将文本小部件的宽度限制为两个图标之间的行布局中的剩余宽度。

通过将子元素包装在 Expanded 中,您可以明确描述每个子小部件在行内的大小。

Expanded 将根据行/列中的其他 Expanded 和剩余空间调整自身大小。

让我们看一个例子来了解 Expanded 如何在行或列中工作:

var row = new Container(
  width: 400.0,
  height: 100.0,
  child: new Row(
    children: [
      // Red Bar
      // This will take up 50dp always, since it is not wrapped by a Expanded
      new Container(
        width: 50.0,
        decoration: new BoxDecoration(
          backgroundColor: Colors.red[500],
        )
      ),
      // Green Bar
      // This will take up 1/3 of the remaining space (1/3 of 350dp)
      new Expanded(
        flex: 1,
        child: new Container(
          decoration: new BoxDecoration(
            backgroundColor: Colors.green[500],
          )
        ),
      ),
      // Blue Bar
      // This will take up 2/3 of the remaining space (2/3 of 350dp)
      new Expanded(
        flex: 2,
        child: new Container(
          decoration: new BoxDecoration(
            backgroundColor: Colors.blue[500],
          )
        ),
      )
    ]
  ),
);

呈现这个:

让我们分解一下:

    红色条 总是 的长度为 50dp,因为它没有包含在 Expanded 中。即使它比父容器大,它也会有 50dp 的宽度。

    现在我们有 350dp (400-350) 在绿条和蓝条之间分配。

    我们现在要做的是将每个 Expanded 的所有剩余 flex 值相加,得到:1[green] + 2[blue] = 3

    现在每个 Expanded 将是剩余空间的一部分,基于 Expanded 的 flex 值和所有 Expanded 的累积 flex 值:绿色 = 1/3,蓝色 = 2/3。

    所以绿色条的宽度为 1/3 * 350 = 116.67dp

    蓝条的宽度为 2/3 * 350 = 233.33dp

回到你原来的问题:你需要做的就是将你的文本小部件包装在一个 Expanded 中。默认情况下,Expanded 的 flex 值为 1。由于您在该行中只有一个 Expanded (1/1 = 100%),因此此文本将占用该行中的剩余空间。

解决方案:

var container = new Container (
  child: new Row (
    children: [
      new Icon (Icons.navigate_before),
      new Expanded(
        child: new Text ("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat."),
      ),      
      new Icon (Icons.navigate_next),
    ],
  ),
  decoration: new BoxDecoration (
    backgroundColor: Colors.grey[300],
  ),
  width: 400.0,
);

【讨论】:

一次更正,我们最近将 Flexible 重命名为 Expanded。 @IanHickson 已修复。

以上是关于如何防止多行文本小部件放置在行中时被剪裁?的主要内容,如果未能解决你的问题,请参考以下文章

如何在android编程中获取放置在小部件上的textview文本

如何防止小部件将自己置于通知栏/摄像头下?

如何防止 PyQt 小部件被掩盖?

展开并在行中展开时,如何在不更改布局的情况下包装小部件列表?

如何删除小部件“步骤”的标题

如何将小部件放置在具有成比例大小和位置的小部件上方