How to use conditional statement within child attribute of a Flutter Widget (Center Widget)
Solution 1
Actually you can use if/else
and switch
and any other statement inline in dart / flutter.
Use an immediate anonymous function
class StatmentExample extends StatelessWidget {
Widget build(BuildContext context) {
return Text((() {
if(true){
return "tis true";}
return "anything but true";
})());
}
}
ie wrap your statements in a function
(() {
// your code here
}())
I would heavily recommend against putting too much logic directly with your UI 'markup' but I found that type inference in Dart needs a little bit of work so it can be sometimes useful in scenarios like that.
Use the ternary operator
condition ? Text("True") : null,
Use If or For statements or spread operators in collections
children: [
...manyItems,
oneItem,
if(canIKickIt)
...kickTheCan
for (item in items)
Text(item)
Use a method
child: getWidget()
Widget getWidget() {
if (x > 5) ...
//more logic here and return a Widget
Redefine switch statement
As another alternative to the ternary operator, you could create a function version of the switch statement such as in the following post https://stackoverflow.com/a/57390589/1058292.
child: case2(myInput,
{
1: Text("Its one"),
2: Text("Its two"),
}, Text("Default"));
Solution 2
I personally use if/else statement in children with this kind of block statement. It only supports on Dart version 2.3.0 above.
if / else
Column(
children: [
if (_selectedIndex == 0) ...[
DayScreen(),
] else ...[
StatsScreen(),
],
],
),
if / else if
Column(
children: [
if (_selectedIndex == 0) ...[
DayScreen(),
] else if(_selectedIndex == 1)...[
StatsScreen(),
],
],
),
multiple widgets example
Column(
children: [
if (_selectedIndex == 0) ...[
DayScreen(),
AboutScreen(),
InfoScreen(),
] else if(_selectedIndex == 1)...[
HomeScreen(),
StatsScreen(),
],
],
),
Solution 3
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.
Using a method and if/else
Widget _buildChild() {
if (condition) {
return ...
}
return ...
}
Widget build(BuildContext context) {
return new Container(child: _buildChild());
}
Using an if/else
Widget build(BuildContext context) {
Widget child;
if (condition) {
child = ...
} else {
child = ...
}
return new Container(child: child);
}
Solution 4
In such a case I would recommand using the ternary operator:
child: condition ? Container() : Center()
and try to avoid code of the form:
if (condition) return A else return B
which is needlessly more verbose than the ternary operator.
But if more logic is needed you may also:
Use the Builder widget
The Builder widget is meant for allowing the use of a closure when a child widget is required:
A platonic widget that calls a closure to obtain its child widget.
It is convenient anytime you need logic to build a widget, it avoids the need to create a dedicated function.
You use the Builder widget as the child, you provide your logic in its builder
method:
Center(
child: Builder(
builder: (context) {
// any logic needed...
final condition = _whateverLogicNeeded();
return condition
? Container();
: Center();
}
)
)
The Builder provides a convenient place to hold the creational logic. It is more straightforward than the immediate anonymous function proposed by atreeon.
Also I agree that the logic should be extracted from the UI code, but when it's really UI logic it is sometimes more legible to keep it there.
Solution 5
For the record, Dart 2.3 added the ability to use if/else statements in Collection literals. This is now done the following way:
return Column(children: <Widget>[
Text("hello"),
if (condition)
Text("should not render if false"),
Text("world")
],);
Related videos on Youtube
Marko
Updated on July 08, 2022Comments
-
Marko almost 2 years
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):
new Center( child: condition == true ? new Container() : new Container() )
Though when I tried using an if/else statement it would lead to an Dead code warning:
new Center( child: if(condition == true){ new Container(); }else{ new Container(); } )
Interestingly enough I tried with a switch case statement and it gives me the same warning and thus I cannot run the code. Am I doing something wrong or is it so that one cannot use if/else or switch statements without flutter thinking there is dead code?
-
Shady Aziza about 6 yearsIf you want to insert a block where widgets should be instantiated you probably better build your widget in class methods
-
Avnish Nishad almost 4 yearsCenter( child:Builder(builder:(context){ if(true) return widget1(); else return widget2(); }) )
-
-
ardi about 5 yearsHow to using it
-
Ajay Kumar almost 5 yearsI tried this and worked for me the exact way. Thanks
-
exequielc almost 5 yearscondition? Text("True"): null, this does an error Asertion false in console, on runtime execution
-
otto almost 5 years@exequielc you must add .where(notNull).toList() and the end of the WidgetList and the method bool notNull(Object o) => o != null;. Try whole example...
-
Brett Sutton almost 5 yearsAs of Dart 2.3 to conditionally include a widget in a list you can use: [Text("Hello"), if(world) Text("World")]
-
Aseem over 4 yearsI have dart 2.5 but I get error running above code. It says ` this code is required to be compatible with earlier versions. try updating SDK constraints`
-
Haojen over 4 yearsemmm, interesting~
-
Matthew Rideout over 4 yearsJust a note if anyone gets stuck, if you are using Provider to rebuild your widgets on global state change, and you are getting data via "Provider.of", your conditional statement may not be re-evaluated until some other action rebuilds your widget. You need to be getting your conditional variable via "Consumer" that is being returned to the Widget build function, then your conditional statement should be properly re-evaluated as global state changes.
-
princebillyGK over 4 yearsDo they add for loop feature? if so how to implement it?
-
yN. about 4 years
-
TechAurelian about 4 yearsDoesn't work with a single widget like
AppBar -> leading:
orchild:
-
cwhisperer about 4 yearsWhat if there is no else condition? In Columns, saying a==b?c:null will not work
-
Afinas EM about 4 yearsYou can simply use SizedBox.shrick() as the second widget. updating the answer.
-
Afinas EM about 4 yearsIf it is a column then you can use if condition directly without else case: `if('condition') widget()'
-
Slamit almost 4 yearsThis should be the correct answer! Thank you for this clarification it helped me!
-
Richardd over 3 yearsIn case someone get an error about the experiment --flow-control-collections. You just need to update your pubspec.yml environment: sdk: ">=2.2.2 <3.0.0". Then do flutter clean, and also clean the cache.
-
Quick learner over 3 yearsthis worked for me pretty well for drawer items click and updating body
-
Kohls over 3 yearsOne of the best things for good practices in dart/flutter
-
Curt Eckhart over 3 years@Aseem - this is because your pubspec.yaml is probably claiming compatability with older versions of dart. Edit the sdk value to declare at least 2.3 on the low value environment: sdk: ">=2.7.0 <3.0.0"
-
Mark Rotteveel over 3 yearsPlease don't post only code as answer, but also provide an explanation what your code does and how it solves the problem of the question. Answers with an explanation are usually more helpful and of better quality, and are more likely to attract upvotes.
-
Nato Boram over 3 yearsThat
...[]
trick is awesome. It's a detail that no other answer mentioned, but it's very useful if you want to add multiple widgets conditionally. -
mahfuz about 3 yearsInteresting! 👍
-
buncis about 3 yearswhich one is better in ternary code? using
null
or emptyContainer()
? -
ritz almost 3 yearsGreat answer! If you have one if-else condition ternary operator should suffice but if you have multiple if-else if-else conditions or switch cases, the Builder widget should be an appropriate solution.
-
Jeppe almost 3 yearsWhat if you have a deep tree, and conditionally want to render something in the tree? Duplicate? Or will I have to split the tree somehow?
-
jauki almost 3 yearswhere can u put the style in, by the immediate anonymous funtion? for exampe: style: TextStyle(color: Colors.white),
-
Drew almost 3 yearsI was getting an error that Column cannot contain null values for the ternary and empty Container() was a work around
-
vin shaba over 2 yearsThis is the most clear explanation to using conditions in attributes
-
Jagadish Nallappa over 2 yearsThank you very much for the explanation. Cheerio!
-
Shady Mohamed Sherif over 2 yearsdoes any one know this works starting from which version of flutter?
-
brendan over 2 years@ShadyMohamedSherif which version you are using now? I started using flutter from 1.17 and it is already working since then. This is nothing special, it's just spreading a list of widgets.
-
Bakhtawar over 2 yearsi wish i knew this way before. Many Thanks :)