Flutter null 安全条件小部件

Posted

技术标签:

【中文标题】Flutter null 安全条件小部件【英文标题】:Flutter null safety conditional widget 【发布时间】:2021-07-07 20:46:22 【问题描述】:

在 Flutter 引入 null-safety 功能之前,我能够有条件地在列表中添加小部件,如下所示:

actions: <Widget>[
  canCancel
    ? CupertinoDialogAction(
        child: Text(cancelActionText),
           onPressed: () 
             Navigator.pop(context);
           ,
      )
    : null,
].where(notNull).toList()

notNull 是一个自制的过滤器,可以过滤掉空对象...

现在有了 null 安全性,这是不可能的,因为 Widget 列表严格必须是非 null 的。 有什么更好的方法?

【问题讨论】:

添加?在 canCancel 上,因此允许为 null 【参考方案1】:

只需在List 中使用if

<Widget>[ 
   if (true) Widget(), 
]

代码示例:

actions: <Widget>[
  if (canCancel)
    CupertinoDialogAction(
        child: Text(cancelActionText),
           onPressed: () 
             Navigator.pop(context);
           ,
      ),
]

【讨论】:

哇,你可以在 Flutter 中做一些“新”的事情吗?不知道这个! @Scaraux 不是。它类似于 Dart 2.5 或 2.6 之类的。它被称为“集合 if”。【参考方案2】:

作为YoBo suggested,在这里使用collection-if 是更好的方法,但如果由于某种原因您需要能够将nulls 存储在List 中并稍后将它们过滤掉(或者如果您更喜欢你现有的风格),你可以:

    更改您的List 类型以允许可为空的元素。也就是说,使用&lt;Widget?&gt;[] 而不是&lt;Widget&gt;[]。 将Iterable.whereType 与不可为空的类型一起使用以过滤掉null 值。
actions: <Widget?>[
  canCancel
    ? CupertinoDialogAction(
        child: Text(cancelActionText),
           onPressed: () 
             Navigator.pop(context);
           ,
      )
    : null,
].whereType<Widget>().toList();

【讨论】:

这也是一个有效的答案。我不需要在列表中包含 null,最终目标是以声明方式有条件地插入小部件。谢谢!【参考方案3】:

只需将您的 null 替换为一个空的、大小为零的 SizedBox

SizedBox(width: 0, height: 0)

或者按照 cmets 中的建议:

SizedBox.shrink()

【讨论】:

SizedBox.shrink() 是实现此目的的正确命名构造函数。【参考方案4】:

if 并不新鲜,因为它是几年前在 Dart 2.3 中添加的。即使在 null 安全性之前,也不允许您为小部件返回 null。在 NNBD 之前您可能看不到编译时警告,但它是运行时错误。

正如我在这个answer 中提到的(虽然这个答案不适合你的情况),你可以使用if 条件甚至像这样的三元运算符:

Column(
  children: [
    if (condition) Text(''),
    condition ? Text('') : Container(),
  ],
)

【讨论】:

以上是关于Flutter null 安全条件小部件的主要内容,如果未能解决你的问题,请参考以下文章

三元条件没有重建我的小部件 - Flutter

在 Flutter 中使用条件选择不同的小部件集

Flutter Visibility with Condition(如何只隐藏一个有条件的小部件)

Flutter:小部件状态:这段代码安全吗?

当结果 api 返回 null 或 /403/404/500/503 状态时,Flutter 在小部件中抛出消息

如果添加到动画列表,Flutter 查找已停用小部件的祖先是不安全的