如何有条件地将小部件添加到列表中?
Posted
技术标签:
【中文标题】如何有条件地将小部件添加到列表中?【英文标题】:How to conditionally add widgets to a list? 【发布时间】:2019-02-03 06:21:15 【问题描述】:在 Flutter 中,Row
/ListView
/Stack
等小部件不处理 null 子级。因此,如果我们想有条件地将小部件添加为子小部件,我通常会执行以下操作:
Row(
children: <Widget>[
foo == 42 ? Text("foo") : Container(),
],
);
但是添加一个空容器感觉很奇怪。
另一种解决方案是where
过滤器:
Row(
children: <Widget>[
foo == 42 ? Text("foo") : null,
].where((t) => t != null).toList(),
);
这样解决了空容器的问题,但是我们仍然有一个丑陋的三元,写起来很累。
有没有更好的解决方案?
【问题讨论】:
【参考方案1】:编辑:
从 Dart 2.2 开始,新语法原生支持这一点:
Column(
children: [
if (foo != null) Text(foo),
Bar(),
],
);
这个问题目前在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;
),
);
【讨论】:
太棒了!List.of(_buildChildren())
怎么样,_buildChildren
是 sync*
方法?
也可以。但是当你想传递参数时使用它有点无聊。关闭使它更容易【参考方案2】:
新的 Dart 语法允许在列表中使用 'if',这导致了这个简单的解决方案:
Row(
children: <Widget>[
if (foo == 42) Text("foo"),
],
);
【讨论】:
【参考方案3】:这是我使用的更简单的版本:
Row(
children: [
Text("always included"),
skipNulls([
icon,
label,
]),
],
);
skipNulls<T>(List<T> items)
return items..removeWhere((item) => item == null);
【讨论】:
【参考方案4】:Row(
children: [
if (_id == 0) ...[
Container()
] else if(_id == 1)...[
Text("Hello")
] else ...[
SizedBox(width: 20)
],
],
),
【讨论】:
以上是关于如何有条件地将小部件添加到列表中?的主要内容,如果未能解决你的问题,请参考以下文章