如何在Flutter Widget(Center Widget)的子属性中使用条件语句

Mar*_*rko 38 dart flutter

到目前为止,每当我需要在Widget中使用条件语句时,我已经完成了以下操作(使用Center和Containers作为简化的虚拟示例):

new Center(
  child: condition == true ? new Container() : new Container()
)
Run Code Online (Sandbox Code Playgroud)

虽然当我尝试使用if/else语句时,它会导致死代码警告:

new Center(
  child: 
    if(condition == true){
      new Container();
    }else{
      new Container();
    }
)
Run Code Online (Sandbox Code Playgroud)

有趣的是,我尝试使用switch case语句,它给了我相同的警告,因此我无法运行代码.我做错了什么或者是不是因为有死代码而无法使用if/else或switch语句而没有颤抖?

bre*_*dan 66

我个人在这种块语句的孩子中使用 if/else 语句。它仅支持 Dart 2.3.0 以上版本。

如果别的

Column(
    children: [
        if (_selectedIndex == 0) ...[
          DayScreen(),
        ] else ...[
          StatsScreen(),
        ],
    ],
 ),
Run Code Online (Sandbox Code Playgroud)

如果/否则如果

Column(
    children: [
        if (_selectedIndex == 0) ...[
          DayScreen(),
        ] else if(_selectedIndex == 1)...[
          StatsScreen(),
        ],
    ],
 ),
Run Code Online (Sandbox Code Playgroud)

多个小部件示例

Column(
    children: [
        if (_selectedIndex == 0) ...[
          DayScreen(),
          AboutScreen(),
          InfoScreen(),
        ] else if(_selectedIndex == 1)...[
          HomeScreen(),
          StatsScreen(),
        ],
    ],
 ),
Run Code Online (Sandbox Code Playgroud)

  • 这个 `...[]` 技巧太棒了。这是其他答案没有提到的细节,但如果您想有条件地添加多个小部件,它非常有用。 (11认同)

mr_*_*ore 51

在这种情况下,我建议使用三元运算符:

child: condition ? Container() : Center()

并尽量避免以下形式的代码:

if (condition) return A else return B

这比三元运算符不必要地更冗长。

但如果需要更多逻辑,您还可以:

使用构建器小部件

生成器插件是为允许使用封闭时,需要一个子控件:

一个柏拉图式的小部件,它调用一个闭包来获取它的子小部件。

任何时候你需要逻辑来构建一个小部件都很方便,它避免了创建专用函数的需要。

您将 Builder 小部件用作子部件,并在其builder方法中提供您的逻辑:

Center(
  child: Builder(
    builder: (context) {
      // any logic needed...
      final condition = _whateverLogicNeeded();
      
      return condition
          ? Container();
          : Center();
    }
  )
)
Run Code Online (Sandbox Code Playgroud)

Builder 提供了一个方便的地方来保存创建逻辑。它比 atreeon 提出的直接匿名函数更直接。

我也同意应该从 UI 代码中提取逻辑,但是当它真的是 UI 逻辑时,有时将其保留在那里更清晰。


小智 40

作为记录,Dart 2.3 添加了在集合文字中使用 if/else 语句的能力。现在通过以下方式完成:

return Column(children: <Widget>[
  Text("hello"),
  if (condition)
     Text("should not render if false"),
  Text("world")
],);
Run Code Online (Sandbox Code Playgroud)

Flutter 问题 #28181 - 列表中的内联条件渲染


Jon*_*ams 38

在Dart中,if/else并且switch语句不是表达式.它们不返回值,因此您无法将它们传递给构造函数参数.如果构建方法中有很多条件逻辑,那么尝试简化它是一个好习惯.例如,您可以将自包含逻辑移动到方法,并使用if/else语句初始化您可以在以后使用的局部变量.

使用方法和if/else

Widget _buildChild() {
  if (condition) {
    return ...
  }
  return ...
}

Widget build(BuildContext context) {
  return new Container(child: _buildChild());
}
Run Code Online (Sandbox Code Playgroud)

用一个 if/else

Widget build(BuildContext context) {
  Widget child;
  if (condition) {
    child = ...
  } else {
    child = ...
  }
  return new Container(child: child);
}
Run Code Online (Sandbox Code Playgroud)


atr*_*eon 28

实际上,您可以在Dart / Flutter中使用if/elseswitch和任何其他内联语句。

使用立即匿名功能

class StatmentExample extends StatelessWidget {
  Widget build(BuildContext context) {
    return Text((() {
      if(true){
        return "tis true";}

      return "anything but true";
    })());
  }
}
Run Code Online (Sandbox Code Playgroud)

即将您的语句包装在一个函数中

(() {
  // your code here
}())
Run Code Online (Sandbox Code Playgroud)

我强烈建议不要在您的UI“标记”中直接添加太多逻辑,但是我发现Dart中的类型推断需要一点工作,因此有时在类似情况下很有用。

使用三元运算符

condition? Text("True"): null,
Run Code Online (Sandbox Code Playgroud)

在集合中使用If或For语句或散布运算符

children: [
  ...manyItems,
  oneItem,
  if(canIKickIt)
    ...kickTheCan
  for (item in items)
    Text(item)
Run Code Online (Sandbox Code Playgroud)

使用方法

child: getWidget()

Widget getWidget() {
  if (x > 5) ...
  //more logic here and return a Widget
Run Code Online (Sandbox Code Playgroud)

重新定义switch语句

作为三元运算符的另一种选择,您可以创建switch语句的函数版本,例如下面的帖子/sf/answers/4017341261/

  child: case2(myInput,
  {
    1: Text("Its one"),
    2: Text("Its two"),
  }, Text("Default"));
Run Code Online (Sandbox Code Playgroud)

  • 我认为,这是最完整的答案,谢谢@orangesherbert (5认同)
  • 请注意,如果有人遇到困难,如果您使用 Provider 在全局状态更改时重建您的小部件,并且您通过“Provider.of”获取数据,则在其他操作重建您的小部件之前,您的条件语句可能不会被重新评估。您需要通过返回到 Widget 构建函数的“Consumer”获取条件变量,然后您的条件语句应该随着全局状态更改而正确地重新评估。 (3认同)

Aym*_*oub 24

最简单的方法:

// the ternary operator:
<conditon>
  ? Widget1()
  : Widget2()

// Or:
if (condition)
    Widget1()

// With else/ if else
if (condition1)
    Widget1()
else if (condition2)
    Widget2()
else
    Widget3(),
Run Code Online (Sandbox Code Playgroud)

如果您想为一个条件渲染多个小部件,您可以使用展开运算符(为此,您必须位于RowColumnStack小部件内):

if (condition) ...[
    Widget1(),
    Widget2(),
  ],

// with else / else if:
if (condition1) ...[
    Widget1(),
    Widget2(),
  ]
else if(condition2)...[
    Widget3(),
    Widget4(),
]
else ...[
    Widget3(),
    Widget4(),
],
Run Code Online (Sandbox Code Playgroud)

  • 多个小部件一直为我服务,谢谢! (2认同)

Afi*_* EM 20

您可以简单地使用条件语句 a==b?c:d

例如 :

Container(
  color: Colors.white,
  child: ('condition')
  ? Widget1(...)
  : Widget2(...)
)
Run Code Online (Sandbox Code Playgroud)

我希望你有这个想法。

假设如果没有其他条件,您可以使用 SizedBox.shrink()

Container(
      color: Colors.white,
      child: ('condition')
       ? Widget1(...)
       : SizedBox.shrink()
    )
Run Code Online (Sandbox Code Playgroud)

如果是列不需要写?:操作符

Column(
 children: <Widget>[
  if('condition')
    Widget1(...),
 ],
)
Run Code Online (Sandbox Code Playgroud)

  • 如果它是一列,那么您可以直接使用 if 条件而无需 else case: `if('condition') widget()' (3认同)

Wil*_*ndi 13

我发现使用条件逻辑构建Flutter UI的一种简单方法是将逻辑保持在UI之外。这是一个返回两种不同颜色的函数:

Color getColor(int selector) {
  if (selector % 2 == 0) {
    return Colors.blue;
  } else {
    return Colors.blueGrey;
  }
}
Run Code Online (Sandbox Code Playgroud)

该功能在下面用于设置CircleAvatar的背景。

new ListView.builder(
  itemCount: users.length,
  itemBuilder: (BuildContext context, int index) {
    return new Column(
      children: <Widget>[
        new ListTile(
          leading: new CircleAvatar(
            backgroundColor: getColor(index),
            child: new Text(users[index].name[0])
          ),
          title: new Text(users[index].login),
          subtitle: new Text(users[index].name),
        ),
        new Divider(height: 2.0),
      ],
    );
  },
);
Run Code Online (Sandbox Code Playgroud)

非常整洁,因为您可以在几个小部件中重复使用颜色选择器功能。

  • 我试过了,并以确切的方式为我工作。谢谢 (2认同)

Tob*_*s K 8

如果您使用小部件列表,则可以使用:

class HomePage extends StatelessWidget {
  bool notNull(Object o) => o != null;
  @override
  Widget build(BuildContext context) {
    var condition = true;
    return Scaffold(
      appBar: AppBar(
        title: Text("Provider Demo"),
      ),
      body: Center(
          child: Column(
        children: <Widget>[
          condition? Text("True"): null,
          Container(
            height: 300,
            width: MediaQuery.of(context).size.width,
            child: Text("Test")
          )
        ].where(notNull).toList(),
      )),
    );
  }
}
Run Code Online (Sandbox Code Playgroud)

  • 从 Dart 2.3 开始,要有条件地将小部件包含在列表中,您可以使用: [Text("Hello"), if(world) Text("World")] (2认同)

小智 8

Lol 经过几个月的使用?:我才发现我可以使用它:

Column(
     children: [
       if (true) Text('true') else Text('false'),
     ],
   )
Run Code Online (Sandbox Code Playgroud)


ale*_*pfx 6

另一种选择:对于 ' switch's' like 语句,有很多条件,我喜欢使用地图:

return Card(
        elevation: 0,
        margin: EdgeInsets.all(1),
        child: conditions(widget.coupon)[widget.coupon.status] ??
            (throw ArgumentError('invalid status')));


conditions(Coupon coupon) => {
      Status.added_new: CheckableCouponTile(coupon.code),
      Status.redeemed: SimpleCouponTile(coupon.code),
      Status.invalid: SimpleCouponTile(coupon.code),
      Status.valid_not_redeemed: SimpleCouponTile(coupon.code),
    };
Run Code Online (Sandbox Code Playgroud)

在不接触条件语句的情况下向条件列表添加/删除元素更容易。

另一个例子:

var condts = {
  0: Container(),
  1: Center(),
  2: Row(),
  3: Column(),
  4: Stack(),
};

class WidgetByCondition extends StatelessWidget {
  final int index;
  WidgetByCondition(this.index);
  @override
  Widget build(BuildContext context) {
    return condts[index];
  }
}
Run Code Online (Sandbox Code Playgroud)


MJ *_*tes 6

除了三元运算符,Builder如果您需要在条件语句之前执行操作,您还可以使用小部件。

Container(
  child: Builder(builder: (context) {
     /// some operation here ...
     if(someCondition) {
       return Text('A');
     }
     else return Text('B');
    })
 )
Run Code Online (Sandbox Code Playgroud)


Ana*_*nan 6

更好的方法

 Column(
        children: [
            if (firstCondition == true) ...[
              DayScreen(),
            ] else if(secondCondition == true)...[
              StatsScreen(),
            ], else...[
              StatsScreen(),
            ],
        ],
     ),
Run Code Online (Sandbox Code Playgroud)


小智 5

这是解决方案。我已经解决了。这是代码

child: _status(data[index]["status"]),

Widget _status(status) {
  if (status == "3") {
    return Text('Process');
  } else if(status == "1") {
    return Text('Order');
  } else {
    return Text("Waiting");
  }
}
Run Code Online (Sandbox Code Playgroud)


Rio*_*ber 5

带按钮

bool _paused = false;

CupertinoButton(
  child: _paused ? Text('Play') : Text('Pause'),
  color: Colors.blue,
  onPressed: () {
    setState(() {
      _paused = !_paused;
    });
  },
),
Run Code Online (Sandbox Code Playgroud)