【问题标题】: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(),
);

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

有没有更好的解决方案?

【问题讨论】:

    标签: flutter dart conditional-statements flutter-widget flutter-listview


    【解决方案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()) 怎么样,_buildChildrensync* 方法?
    • 也可以。但是当你想传递参数时使用它有点无聊。关闭使它更容易
    【解决方案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)
                ],
            ],
         ),

        【讨论】:

          猜你喜欢
          • 2019-11-26
          • 2021-03-01
          • 1970-01-01
          • 2018-07-19
          • 1970-01-01
          • 2015-05-06
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多