So far whenever I needed to use a conditional statement within a Widget I have done the following (Using Center and Containers as simplified dummy examples):
if you use a list of widgets you can use this:
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(),
)),
);
}
}
You can simply use a conditional statement a==b?c:d
For example :
Container(
color: Colors.white,
child: ('condition')
? Widget1(...)
: Widget2(...)
)
I hope you got the idea.
Suppose if there is no else condition you can use a SizedBox.shrink()
Container(
color: Colors.white,
child: ('condition')
? Widget1(...)
: SizedBox.shrink()
)
If it is a column no need to write ?:
operator
Column(
children: <Widget>[
if('condition')
Widget1(...),
],
)
You can use ternary operator for conditional statements in dart, It's use is simple
(condition) ? statement1 : statement2
if the condition
is true then the statement1
will be executed otherwise statement2
.
Taking a practical example
Center(child: condition ? Widget1() : Widget2())
Remember if you are going to use null
as Widget2
it is better to use SizedBox.shrink()
because some parent widgets will throw an exception after getting a null
child.
In Dart, if/else
and switch
are statements not expressions. They don't return a value so you can't pass them to constructor params. If you have a lot of conditional logic in your build method, then it is a good practice to try and simplify it. For example, you can move self-contained logic to methods, and use if/else
statements to initialize local variables which you can later use.
Widget _buildChild() {
if (condition) {
return ...
}
return ...
}
Widget build(BuildContext context) {
return new Container(child: _buildChild());
}
if/else
Widget build(BuildContext context) {
Widget child;
if (condition) {
child = ...
} else {
child = ...
}
return new Container(child: child);
}
I found out that an easy way to use conditional logic to build Flutter UI is to keep the logic outside of the UI. Here is a function to return two different colors:
Color getColor(int selector) {
if (selector % 2 == 0) {
return Colors.blue;
} else {
return Colors.blueGrey;
}
}
The function is used below to to set the background of the 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),
],
);
},
);
Very neat as you can reuse your color selector function in several widgets.
Another alternative: for 'switch's
' like statements, with a lot of conditions, I like to use maps:
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),
};
It's easier to add/remove elements to the condition list without touch the conditional statement.
Another example:
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];
}
}