Jusqu'à présent, chaque fois que j'avais besoin d'utiliser une instruction conditionnelle dans un widget, j'ai procédé comme suit (Utilisation de Center et Containers comme exemples factices simplifiés):
new Center(
child: condition == true ? new Container() : new Container()
)
Bien que, lorsque j'ai essayé d'utiliser une instruction if/else, cela conduirait à un avertissement de code mort:
new Center(
child:
if(condition == true){
new Container();
}else{
new Container();
}
)
Chose intéressante, j'ai essayé avec une déclaration de cas de commutation, qui me donne le même avertissement et ne peut donc pas exécuter le code. Est-ce que je fais quelque chose de mal ou est-ce que l'on ne peut pas utiliser if/else ou changer d'instruction sans clignoter en pensant qu'il y a du code mort?
Dans Dart, if/else
et switch
sont des instructions et non des expressions. Ils ne renvoient pas de valeur, vous ne pouvez donc pas les transmettre aux paramètres du constructeur. Si votre méthode de génération contient beaucoup de logique conditionnelle, il est recommandé d'essayer de la simplifier. Par exemple, vous pouvez déplacer une logique autonome vers des méthodes et utiliser les instructions if/else
pour initialiser les variables locales que vous pourrez utiliser par la suite.
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);
}
J'ai découvert qu'un moyen simple d'utiliser la logique conditionnelle pour créer une interface utilisateur Flutter est de conserver la logique en dehors de l'interface utilisateur. Voici une fonction pour renvoyer deux couleurs différentes:
Color getColor(int selector) {
if (selector % 2 == 0) {
return Colors.blue;
} else {
return Colors.blueGrey;
}
}
La fonction est utilisée ci-dessous pour définir l'arrière-plan de 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),
],
);
},
);
Très soigné car vous pouvez réutiliser votre sélecteur de couleur dans plusieurs widgets.
En fait, vous pouvez utiliser if/else
et switch
et toute autre instruction en ligne dans Dart/Flutter.
class StatmentExample extends StatelessWidget {
Widget build(BuildContext context) {
return Text((() {
if(true){
return "tis true";}
return "anything but true";
})());
}
}
c.-à-d. envelopper vos déclarations dans une fonction
(() {
// your code here
}())
Je recommande fortement de ne pas mettre trop de logique directement dans votre 'balise' d'interface utilisateur, mais j'ai trouvé que l'inférence de type dans Dart nécessite un peu de travail, ce qui peut parfois être utile dans de tels scénarios.
condition? Text("True"): null,
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
Comme alternative aux opérateurs ternaires, vous pouvez créer une version de fonction de l’instruction switch, comme dans le message suivant https://stackoverflow.com/a/57390589/1058292 .
child: case2(myInput,
{
1: Text("Its one"),
2: Text("Its two"),
}, Text("Default"));
Voici la solution. Je l'ai réparé Voici le code
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");
}
}
si vous utilisez une liste de widgets, vous pouvez utiliser ceci:
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(),
)),
);
}
}
**** Vous pouvez également utiliser des conditions en utilisant cette méthode ** **
int _moneyCounter = 0;
void _rainMoney(){
setState(() {
_moneyCounter += 100;
});
}
new Expanded(
child: new Center(
child: new Text('\$$_moneyCounter',
style:new TextStyle(
color: _moneyCounter > 1000 ? Colors.blue : Colors.amberAccent,
fontSize: 47,
fontWeight: FontWeight.w800
)
),
)
),
Une autre alternative: pour les instructions 'switch's
', avec beaucoup de conditions, j'aime utiliser des cartes:
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),
};
Il est plus facile d'ajouter/supprimer des éléments à la liste de conditions sans toucher à l'instruction conditionnelle.
Un autre exemple:
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];
}
}