在 Flutter 中通过迭代一个列表来呈现多个小部件?

我有一个如下定义的字符串列表:

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

我想使用文本小部件并排显示屏幕上的值。我尝试使用以下代码尝试这样做:

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

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

248746 次浏览

当您返回一些内容时,代码退出循环,不管您返回的内容是什么。因此,在您的代码中,在第一次迭代中,名称是 "one"。因此,一旦到达 return new Text(name),代码就用 return new Text("one")退出循环。因此,尝试打印它或使用异步返回。

您可以使用 ListView 来呈现项目列表。但是如果你不想使用 ListView,你可以创建一个方法来返回一个 Widgets 列表(在你的例子中是文本) ,如下所示:

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

Dart 语言包含函数式编程的方方面面,所以您想要的可以简洁地写成:

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

把它理解为“将 list中的每个 name映射到 Text并将它们重新构成 List”。

基本上,当你在一个函数上点击“ return”,函数就会停止并且不会继续你的迭代,所以你需要做的就是把它放到一个列表中,然后把它作为一个小部件的子部件添加进去

你可以这样做:

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

现在可以在 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 关键字。

对于 Google,我编写了一个简单的无状态小部件,其中包含本 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(),
);
}
}

要循环通过具有多个子部件的 for 循环,

children: [
for(int i = 0; i < item.length; i++) ...[
Widget1,
Widget2,
...
],
],

下面的作品为我使用的集合包:

Https://pub.dev/packages/collection

children: <Widget>[
...languages.mapIndex((idx, item) {
return InkWell(
child: CustomCheckbox(Skill(item, _languageSelections[idx])),
onTap: () {
setState(() {
_languageSelections[idx] = !_languageSelections[idx];
});
});
})
],

如果以数组的形式从 http 请求接收响应,则可以使用 < strong > ListView.Builder ()

列出项目 = 数据;

Container(
child: ListView.builder(
shrinkWrap: true,
itemCount: items.length,
itemBuilder: (BuildContext context, int index){
return Container(
child: Text(
items[index]['property']
),
);
},
),
);

在哪里 Data 是使用 post 或 get 从 http 请求返回的内容 Item 是数组 “ 财产”是数组中每个项目的属性之一,假设您正在接收回一个对象列表

最简单的方法是将列表映射到 Row 或 Column 小部件中:

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


Widget build(BuildContext context) {
return Row(children: List.from(list.map((name) => Text(name))));
}

更简单的方法可能是使用 expand:

比如说

var paragraphs = ['Para1','Para2','Para3'];

在你的小部件树的某个地方你可以这样做:

...paragraphs.expand((value) => [
SizedBox(
height: 10.0,
),
Text(
value,
// Add some styling if necessary
),
SizedBox(
height: 20.0,
),
]),

这里,expand返回一个可迭代的小部件,然后使用传播操作符(...)传播这些小部件。

就一句

Column( children: list.map((e) => Text(e)).toList() )