到目前为止,当我需要在小部件中使用条件语句时,我已经做了以下工作(使用中心和容器作为简化的虚拟示例):
new Center(
child: condition == true ? new Container() : new Container()
)
虽然当我尝试使用if/else语句时,它会导致一个死亡代码警告:
new Center(
child:
if(condition == true){
new Container();
}else{
new Container();
}
)
有趣的是,我尝试了一个switch case语句,它给了我同样的警告,因此我不能运行代码。我做错了什么,或者它是这样的,不能使用if/else或开关语句而不颤振认为有死代码?
编辑:我不再推荐我在下面发布的解决方案,因为我意识到使用这种方法,生成了真实结果的子结果和虚假结果的子结果,但只使用了一个,这不必要地降低了代码的速度。
之前的回答:
在我的应用程序中,我创建了一个WidgetChooser小部件,这样我就可以在没有条件逻辑的小部件之间进行选择:
WidgetChooser(
condition: true,
trueChild: Text('This widget appears if the condition is true.'),
falseChild: Text('This widget appears if the condition is false.'),
);
这是WidgetChooser小部件的源代码:
import 'package:flutter/widgets.dart';
class WidgetChooser extends StatelessWidget {
final bool condition;
final Widget trueChild;
final Widget falseChild;
WidgetChooser({@required this.condition, @required this.trueChild, @required this.falseChild});
@override
Widget build(BuildContext context) {
if (condition) {
return trueChild;
} else {
return falseChild;
}
}
}
实际上,你可以在dart / flutter中使用if/else和switch以及任何其他语句。
使用立即匿名函数
class StatmentExample extends StatelessWidget {
Widget build(BuildContext context) {
return Text((() {
if(true){
return "tis true";}
return "anything but true";
})());
}
}
即把你的语句包装在一个函数中
(() {
// your code here
}())
我强烈建议不要把太多的逻辑直接放在你的UI“标记”上,但我发现Dart中的类型推断需要一些工作,所以它有时在这种情况下很有用。
使用三元运算符
condition ? Text("True") : null,
在集合中使用If或For语句或展开运算符
children: [
...manyItems,
oneItem,
if(canIKickIt)
...kickTheCan
for (item in items)
Text(item)
使用方法
child: getWidget()
Widget getWidget() {
if (x > 5) ...
//more logic here and return a Widget
重定义switch语句
作为三元操作符的另一种选择,您可以创建switch语句的函数版本,例如下面的帖子https://stackoverflow.com/a/57390589/1058292。
child: case2(myInput,
{
1: Text("Its one"),
2: Text("Its two"),
}, Text("Default"));
Flutter Widget可以在不破坏代码树的情况下有条件地用父元素包装子树
import 'package:flutter/widgets.dart';
/// Conditionally wrap a subtree with a parent widget without breaking the code tree.
///
/// [condition]: the condition depending on which the subtree [child] is wrapped with the parent.
/// [child]: The subtree that should always be build.
/// [conditionalBuilder]: builds the parent with the subtree [child].
///
/// ___________
/// Usage:
/// ```dart
/// return ConditionalParentWidget(
/// condition: shouldIncludeParent,
/// child: Widget1(
/// child: Widget2(
/// child: Widget3(),
/// ),
/// ),
/// conditionalBuilder: (Widget child) => SomeParentWidget(child: child),
///);
/// ```
///
/// ___________
/// Instead of:
/// ```dart
/// Widget child = Widget1(
/// child: Widget2(
/// child: Widget3(),
/// ),
/// );
///
/// return shouldIncludeParent ? SomeParentWidget(child: child) : child;
/// ```
///
class ConditionalParentWidget extends StatelessWidget {
const ConditionalParentWidget({
Key key,
@required this.condition,
@required this.child,
@required this.conditionalBuilder,
}) : super(key: key);
final Widget child;
final bool condition;
final Widget Function(Widget child) conditionalBuilder;
@override
Widget build(BuildContext context) {
return condition ? this.conditionalBuilder(this.child) : this.child;
}
}