如何有条件地将小部件添加到列表?

时间:2018-08-28 14:56:52

标签: flutter

在混乱中,Row / ListView / Stack之类的小部件无法处理空子级。因此,如果我们要有条件地将小部件添加为子级,我通常会执行以下操作:

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

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

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

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

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

有更好的解决方案吗?

3 个答案:

答案 0 :(得分:4)

此问题目前在github here上有争议。

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

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;
  }),
);

答案 1 :(得分:0)

这是我使用的简单版本:

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

skipNulls<T>(List<T> items) {
  return items..removeWhere((item) => item == null);
}

答案 2 :(得分:0)

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

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