38

在 Flutter 中,// 等小部件不Row处理null 子级。因此,如果我们想有条件地将小部件添加为子项,我通常会执行以下操作:ListViewStack

Row(
  children: <Widget>[
    foo == 42 ? Text("foo") : Container(),
  ],
);

但是添加一个空容器感觉很奇怪。

另一种解决方案是where过滤器:

Row(
  children: <Widget>[
    foo == 42 ? Text("foo") : null,
  ].where((t) => t != null).toList(),
);

这样就解决了空容器问题,但我们仍然有一个丑陋的三元组,写起来很累。

有没有更好的解决方案?

4

4 回答 4

72

编辑

从 Dart 2.2 开始,新语法原生支持这一点:

Column(
  children: [
    if (foo != null) Text(foo),
    Bar(),
  ],
);

这个问题目前在 github 上讨论。

但现在,您可以使用 dartsync*函数:

Row(
  children: toList(() sync* {
    if (foo == 42) {
      yield Text("foo");
    }
  }),
);

哪里toList是:

typedef Iterable<T> IterableCallback<T>();

List<T> toList<T>(IterableCallback<T> cb) {
  return List.unmodifiable(cb());
}

不仅解决了条件加法问题;由于yield*. 例子:

List<Widget> foo;

Row(
  children: toList(() sync* {
    yield Text("Hello World");
    yield* foo;
  }),
);
于 2018-08-28T14:56:51.730 回答
3

这是我使用的一个更简单的版本:

Row(
  children: [
    Text("always included"),
    skipNulls([
      icon,
      label,
    ]),
  ],
);

skipNulls<T>(List<T> items) {
  return items..removeWhere((item) => item == null);
}
于 2019-03-07T11:37:42.573 回答
3

新的 Dart 语法允许在列表中使用 'if',这导致了这个简单的解决方案:

Row(
  children: <Widget>[
    if (foo == 42) Text("foo"),
  ],
);
于 2019-06-28T19:49:12.087 回答
0

Row(
    children: [
        if (_id == 0) ...[
          Container()
        ] else if(_id == 1)...[
          Text("Hello")
        ] else ...[
          SizedBox(width: 20)
        ],
    ],
 ),

于 2022-01-19T06:05:25.643 回答