Flutter:小部件压缩优先级

Posted

技术标签:

【中文标题】Flutter:小部件压缩优先级【英文标题】:Flutter: Widget compression priority 【发布时间】:2022-01-23 05:48:04 【问题描述】:

我是 Flutter 的初学者,现在我尝试了解如何设置小部件压缩优先级的布局。例如我想要的:

我有Horizontal StackRow 一样,里面有:

一些空格,比如SizedBox,然后是一些Text。当文本溢出它们自身空间时,我想减少文本之前的空间。

os ios 它通过布局约束中的压缩优先级来解决,但我如何在颤振上做同样的事情?

我当前的代码

          Row(
            mainAxisSize: MainAxisSize.min,
            children: <Widget>[
              SizedBox(width: titleWidth),
              Expanded(child: subline),
            ],
          )

其中titleWidth 是宽度空间,应在subline 小部件小于剩余可访问大小pinkSpace 时应用。 subline 是一个小部件。在示例中,它是Text

但代码仅在带有“但这个...”的卡片上工作,它不会减少文本小部件之前的空间。

【问题讨论】:

【参考方案1】:

间距小部件

Flutter 有很多小部件可以帮助设置间距 - 在 RowColumn 等内部小部件中,它们会接收子列表。

F.ex:

Spacer - 填充其他子小部件之间空间的小部件。 Flexible - 包装一个小部件并允许您定义一个 flex 值以影响该小部件与子列表中的其他小部件相比应占用多少空间。 Expanded - 如果你在其中包装一个小部件,你会让一个小部件填满剩余的空间。 ConstrainedBox - 允许为子小部件设置 minWidth、maxWidth、minHeight、maxHeight。

代码示例

根据您的要求:

    单行文本有缩进 多行文本没有缩进

SizedBox 是不行的

SizedBox 不适用于多行文本,因为 Row 中的多行 Text 必须包含在 Flexible (Flutter - multiline label inside row) 中,并且 SizedBox 将始终占据您设置的任何宽度- Spacer、Flexible 或 Expanded 的组合似乎在这里不起作用。

替代解决方案

一种选择是指定 Row 并将 mainAxisAlignment 设置为 MainAxisAlignment.end 并使用带有 MediaQuery 的 BoxConstraint 减去我们想要的文本容器的 minWidth 的屏幕宽度。

这实际上与 SizedBox 尝试相反。
class IndentedText extends StatelessWidget 
  const IndentedText(Key? key, required this.text, this.textMinWidth = 150) : super(key: key);

  final String text;
  final double textMinWidth;

  @override
  Widget build(BuildContext context) 
    return Row(
      mainAxisAlignment: MainAxisAlignment.end,
      mainAxisSize: MainAxisSize.max,
      children: [
        Flexible(
          child: ConstrainedBox(
            constraints: BoxConstraints(minWidth: MediaQuery.of(context).size.width - textMinWidth),
            child: Text(text),
          ),
        ),
      ],
    );
  

然后是widget的用法

class SpacingExample extends StatelessWidget 
  const SpacingExample(Key? key) : super(key: key);

  @override
  Widget build(BuildContext context) 
    return Column(
      mainAxisAlignment: MainAxisAlignment.center,
      children: [
        Card(
          child: Column(
            children: const [
              IndentedText(text: "text"),
              IndentedText(
                text:
                    "A vehicle is a object people use to get around more easily, etc etc make the text longer and multiline.",
              )
            ],
          ),
        ),
      ],
    );
  

外观:

注意:对于更复杂的用例,当您减去 minWidth - 如果布局有多个列 f.ex. 以及可能的填充大小,您可能还需要减去其他小部件的大小。李>

【讨论】:

但如果文本不会自己溢出,我需要在文本前留出空格 用一个解决方案编辑答案,有点粗糙,但它有效? 可能我不太清楚,请看我的截图。除了带有文本“但不是这个......”的卡片外,我寻找屏幕截图上的行为。在这张卡片上,我展示了当前的行为。 啊,所以您希望它在适合时与车辆图标左对齐并且不希望它多行,而是如果省略号扩展到整行之外,您希望省略号溢出?如果是这样,请尝试在我制作的 IndentedText 小部件中设置 Text 小部件的属性:maxLines: 1overflow: TextOverflow.ellipsis 已经完成了,我的问题是——文本溢出时如何减少剩余空间【参考方案2】:

试试这个代码,我希望这个

  @override
  Widget build(BuildContext context) 
    return Column(
      mainAxisAlignment: MainAxisAlignment.start,
      children: [
        Expanded(
           child: Row(
        mainAxisAlignment: MainAxisAlignment.start,
        mainAxisSize: MainAxisSize.min,
        children: <Widget>[
          SizedBox(width: titleWidth),
          Expanded(child:Card( child: subline)),
        ],
      )
        
    );
  

【讨论】:

如果出现错误,请尝试使用 Expanded 的父列换行【参考方案3】:

我没有看到你的代码,但你可以使用卡片小部件,它可以工作

【讨论】:

它只能作为“但是这个......”它不会减少文本小部件之前的空间 你能分享一些关于你的项目的代码示例吗? 我已经在我的问题中添加了一些代码。但它没有什么特别的

以上是关于Flutter:小部件压缩优先级的主要内容,如果未能解决你的问题,请参考以下文章

iOS的一个小技巧——AutoLayout约束的优先级

闪亮的小部件,以更改向量中的元素的顺序

小鹤音形指引

Tkinter 标签的优先级

自定义小部件的 Flutter 小部件测试失败

Flutter:是不是可以替换小部件本身?