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
是更好的方法,但如果由于某种原因您需要能够将null
s 存储在List
中并稍后将它们过滤掉(或者如果您更喜欢你现有的风格),你可以:
-
更改您的
List
类型以允许可为空的元素。也就是说,使用<Widget?>[]
而不是<Widget>[]
。
将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 Visibility with Condition(如何只隐藏一个有条件的小部件)