遍历列表以在Flutter中渲染多个小部件?


76

我有这样定义的字符串列表:

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

我想使用文本小部件在屏幕上并排显示值。我试图使用以下代码来尝试此操作:

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

但是,当我运行此代码时,for循环仅运行一次,并且仅呈现一个文本小部件,该小部件显示one(列表中的第一项)。另外,当我在for循环中添加一条日志消息时,它也会被触发一次。为什么我的for循环不是基于列表的长度?它似乎只运行一次,然后退出。


为什么不使用ListView?您能否分享更多有关您的工作方式的代码?
Phuc Tran

Answers:


153

基本上,当您在某个函数上点击“返回”时,该函数将停止并且不会继续进行迭代,因此您需要做的是将其全部放入列表中,然后将其添加为小部件的子级

您可以执行以下操作:

  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);
  }

甚至更好,您可以使用.map()运算符并执行以下操作:

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

1
是否还可能返回小部件的数组?
KT Works

5
从dart 2.3开始,您可以使用新的for循环方法return Row(children: [ for (var name in list) Text(name) ])
smac89 '20

70

现在,可以通过在集合中使用for元素在Flutter 1.5和Dart 2.3中实现这一目标。

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

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

这将显示四个Text小部件,其中包含列表中的项目。
注意 for循环中没有大括号,也没有return关键字。


嗨,我可能迟到了,但是我想知道如果我想在一个循环中显示多个小部件该怎么办?
Faran Khan

您可以将它们包装在一个列或可以容纳多个窗口小部件的任何窗口小部件中。如果我明白你的问题。
nonybrighto19年

1
如何在循环中放置多个元素?例如,for(var item in list ) { Text(item),Spacer() }将无法正常工作。
A-letubby

2
U将需要将两个小部件包装在另一个小部件中。
nonybrighto

37

Dart语言具有功能编程的各个方面,因此您想要的内容可以简洁地编写为:

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

将此读为“将每个name输入list并映射到一个,Text然后将它们重新组合成一个List”。


2
我认为这比标记为“好”的答案更好,因为您实际上可以直接在build函数中使用此函数,而不必调用返回小部件的函数
Jose Jet,

如何获取该.map中的索引?
丹妮

1
@dani您不能使用地图,但是可以使用rizky的答案中的for循环
Richard Heap

27

对于googler,我写了一个简单的Stateless Widget,其中包含本SO中提到的3种方法。希望这使它更容易理解。

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

1

您可以使用ListView呈现项目列表。但是,如果您不想使用ListView,则可以创建一个返回Widget列表(在您的情况下为Text)的方法,如下所示:

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
List <Text>不是小部件兄弟的子类型

它仍然对我有效。收到错误消息了吗?(我更新了代码,增加了1种方法)
Phuc Tran

1

您需要做的就是将其放在列表中,然后将其添加为小部件的子级。

您可以执行以下操作:

Widget listOfWidgets(List<String> item) {
  List<Widget> list = List<Widget>();
  for (var i = 0; i < item.length; i++) {
    list.add(Container(
        child: FittedBox(
          fit: BoxFit.fitWidth,
          child: Text(
            item[i],
          ),
        )));
  }
  return Wrap(
      spacing: 5.0, // gap between adjacent chips
      runSpacing: 2.0, // gap between lines
      children: list);
}

这样的通话之后

child: Row(children: <Widget>[
   listOfWidgets(itemList),
])

在此处输入图片说明


0

当您返回某些内容时,代码将与您返回的内容一起退出循环。因此,在代码中,在第一次迭代中,名称为"one"。因此,一旦到达return new Text(name),代码就会通过退出循环return new Text("one")。因此,尝试打印它或使用异步返回。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.