web-dev-qa-db-fra.com

Comment utiliser une instruction conditionnelle dans l'attribut enfant d'un widget Flutter (widget Centre)

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?

26
Marko

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.

Utiliser une méthode et si/sinon

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

Widget build(BuildContext context) {
  return new Container(child: _buildChild());
}

Utiliser un if/else

Widget build(BuildContext context) {
  Widget child;
  if (condition) {
    child = ...
  } else {
    child = ...
  }
  return new Container(child: child);
}
29
Jonah Williams

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.

10
Willie Nandi

En fait, vous pouvez utiliser if/else et switch et toute autre instruction en ligne dans Dart/Flutter.

Utiliser une fonction anonyme immédiate

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.

Utiliser l'opérateur ternaire

condition? Text("True"): null,

Utilisez les instructions If ou For ou les opérateurs d'étalement dans les collections

children: [
  ...manyItems,
  oneItem,
  if(canIKickIt)
    ...kickTheCan
  for (item in items)
    Text(item)

Utiliser une méthode

child: getWidget()

Widget getWidget() {
  if (x > 5) ...
  //more logic here and return a Widget

Redéfinir l'instruction de commutateur

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"));
6
orangesherbert

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");
  }
}
6
Yasir Malik

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(),
      )),
    );
  }
}
2
Tobias K

**** 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
            )

            ),
          ) 
        ),
0
Hamza Tanveer

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];
  }
}
0
alexpfx