一尘不染

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

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

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

有没有更好的解决方案?


阅读 253

收藏
2020-08-13

共1个答案

一尘不染

编辑

从Dart 2.2开始,新语法原生支持此功能:

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

这个问题目前正在讨论在github
这里

但是现在,您可以使用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;
  }),
);
2020-08-13