98 votes

L'itération dans une liste pour rendre plusieurs widgets dans Flutter ?

J'ai une liste de chaînes de caractères définies comme ceci :

var list = ["one", "two", "three", "four"]; 

Je veux rendre les valeurs à l'écran côte à côte en utilisant des widgets de texte. J'ai essayé d'utiliser le code suivant pour y parvenir :

for (var name in list) {
   return new Text(name);
}

Cependant, lorsque j'exécute ce code, la boucle for ne s'exécute qu'une seule fois et un seul widget de texte est rendu, qui dit one (le premier élément de la liste). De plus, lorsque j'ajoute un message de journal dans ma boucle for, il est également déclenché une fois. Pourquoi ma boucle for ne fonctionne-t-elle pas en fonction de la longueur de la liste ? Il semble ne s'exécuter qu'une seule fois, puis s'arrêter.

1 votes

Pourquoi n'utilisez-vous pas ListView ? Pouvez-vous partager plus de code sur la façon dont vous procédez ?

184voto

Rizky Andriawan Points 1076

En fait, lorsque vous appuyez sur la touche "return" d'une fonction, celle-ci s'arrête et ne poursuit pas l'itération. Vous devez donc placer tous les éléments dans une liste, puis les ajouter comme enfants d'un widget.

vous pouvez faire quelque chose comme ça :

  Widget getTextWidgets(List<String> strings)
  {
    List<Widget> list = new List<Widget>();
    for(var i = 0; i < strings.length; i++){
        list.add(new Text(strings[i]));
    }
    return new Row(children: list);
  }

ou encore mieux, vous pouvez utiliser l'opérateur .map() et faire quelque chose comme ceci :

  Widget getTextWidgets(List<String> strings)
  {
    return new Row(children: strings.map((item) => new Text(item)).toList());
  }

1 votes

est-il également possible de renvoyer un tableau de Widgets ?

14 votes

Depuis la version 2.3 de Dart, vous pouvez utiliser la nouvelle fonction méthode de la boucle for : return Row(children: [ for (var name in list) Text(name) ])

88voto

nonybrighto Points 1157

Il est maintenant possible d'y parvenir dans Flutter 1.5 et Dart 2.3 en utilisant un pour dans votre collection.

var list = ["one", "two", "three", "four"]; 

child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
             for(var item in list ) Text(item)
          ],
        ),    

Cela affichera quatre widgets Texte contenant les éléments de la liste.
NB. Pas d'accolades autour de la boucle for et pas de mot clé return.

0 votes

Bonjour, je suis peut-être un peu en retard, mais j'ai besoin de savoir ce que je dois faire si je veux que plusieurs widgets s'affichent en boucle ?

0 votes

Vous pouvez les intégrer dans une colonne ou dans tout autre widget pouvant contenir plusieurs widgets. Si j'ai bien compris votre question.

1 votes

Comment puis-je mettre plus d'un élément dans la boucle ? Par exemple for(var item in list ) { Text(item),Spacer() } ne fonctionnerait pas.

41voto

Richard Heap Points 15826

Le langage Dart présente des aspects de la programmation fonctionnelle, de sorte que ce que vous voulez peut être écrit de manière concise comme :

List<String> list = ['one', 'two', 'three', 'four'];
List<Widget> widgets = list.map((name) => new Text(name)).toList();

Lire ceci comme "prendre chaque name sur list et de le faire correspondre à un Text et de les reformer en un List ".

2 votes

Je pense que cette réponse est meilleure que celle qui est marquée comme bonne, car vous pouvez l'utiliser directement dans la fonction de construction sans avoir à appeler une fonction qui renvoie un widget.

0 votes

comment puis-je obtenir l'index dans ce .map ?

1 votes

@dani vous ne pouvez pas avec map, mais vous pouvez avec la boucle for dans la réponse de rizky

34voto

user2875289 Points 1065

Pour le googler, j'ai écrit un simple widget apatride contenant les 3 méthodes mentionnées dans ce SO. J'espère que cela rendra la compréhension plus facile.

import 'package:flutter/material.dart';

class ListAndFP extends StatelessWidget {
  final List<String> items = ['apple', 'banana', 'orange', 'lemon'];

  //  for in (require dart 2.2.2 SDK or later)
  Widget method1() {
    return Column(
      children: <Widget>[
        Text('You can put other Widgets here'),
        for (var item in items) Text(item),
      ],
    );
  }

  // map() + toList() + Spread Property
  Widget method2() {
    return Column(
      children: <Widget>[
        Text('You can put other Widgets here'),
        ...items.map((item) => Text(item)).toList(),
      ],
    );
  }

  // map() + toList()
  Widget method3() {
    return Column(
      // Text('You CANNOT put other Widgets here'),
      children: items.map((item) => Text(item)).toList(),
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: method1(),
    );
  }
}

2voto

phuc_tran Points 76

Vous pouvez utiliser ListView pour rendre une liste d'éléments. Mais si vous ne voulez pas utiliser ListView, vous pouvez créer une méthode qui renvoie une liste de Widgets (Textes dans votre cas) comme ci-dessous :

var list = ["one", "two", "three", "four"];

    @override
    Widget build(BuildContext context) {
      return new MaterialApp(
          home: new Scaffold(
        appBar: new AppBar(
          title: new Text('List Test'),
        ),
        body: new Center(
          child: new Column( // Or Row or whatever :)
            children: createChildrenTexts(),
          ),
        ),
      ));
    }

     List<Text> createChildrenTexts() {
    /// Method 1
//    List<Text> childrenTexts = List<Text>();
//    for (String name in list) {
//      childrenTexts.add(new Text(name, style: new TextStyle(color: Colors.red),));
//    }
//    return childrenTexts;

    /// Method 2
    return list.map((text) => Text(text, style: TextStyle(color: Colors.blue),)).toList();
  }

2 votes

List<Text> n'est pas un sous-type de Widget bro

0 votes

Ça marche toujours de mon côté. Avez-vous eu une erreur ? (J'ai mis à jour mon code pour ajouter 1 méthode supplémentaire)

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X