遍历列表以在 Flutter 中呈现多个小部件?

Posted

技术标签:

【中文标题】遍历列表以在 Flutter 中呈现多个小部件?【英文标题】:Iterating through a list to render multiple widgets in Flutter? 【发布时间】:2018-10-30 15:46:05 【问题描述】:

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

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

我想使用文本小部件并排呈现屏幕上的值。我尝试使用以下代码来尝试:

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

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

【问题讨论】:

为什么不用ListView?你能分享更多关于你如何做的代码吗? 【参考方案1】:

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

你可以这样做:

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

【讨论】:

是否也可以返回一个Widgets数组? 从dart 2.3开始,你可以使用新的for loop method:return Row(children: [ for (var name in list) Text(name) ])【参考方案2】:

现在可以通过在您的集合中使用 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 关键字。

【讨论】:

嗨,我可能有点晚了,但是我需要知道如果我想循环显示多个小部件该怎么办? 您可以将它们包装在一个列或任何可以容纳多个小部件的小部件中。如果我清楚你的问题。 如何在循环中放置多个元素?例如。 for(var item in list ) Text(item),Spacer() 不起作用。 U 需要将两个小部件包装在另一个小部件中。 这很有帮助,特别是如果您想迭代地添加一些小部件,而其他一些小部件则手动添加到同一列。【参考方案3】:

Dart 语言具有函数式编程的方面,所以你想要的可以简洁地写成:

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

将其读作“将list 中的每个name 映射到Text 并将它们重新组合成List”。

【讨论】:

我认为这比标记为好的答案更好,因为您实际上可以直接在构建函数中使用它,而无需调用返回小部件的函数 我怎样才能获得该 .map 中的索引? @dani 你不能用地图,但你可以用 rizky 回答中的 for 循环 list.map((name) => new Text(name)).toList();我忘了在最后添加 toList() 函数。谢谢兄弟:)【参考方案4】:

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

【讨论】:

【参考方案5】:

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

你可以这样做:

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),
])

【讨论】:

【参考方案6】:

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

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

【讨论】:

List 不是 Widget bro 的子类型 它仍然对我有用。你得到错误了吗? (我更新了我的代码以添加 1 个方法)【参考方案7】:

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

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

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

【讨论】:

有帮助。谢谢【参考方案8】:

要在子项中有多个小部件的 for 循环中循环,

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

【讨论】:

例如,如果您需要索引来检查所选项目,这很有用。【参考方案9】:

如果您收到来自作为数组的 http 请求的响应,则可以使用 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 是数组 'property' 是数组中每个项目的属性之一,假设您正在接收一个对象列表

【讨论】:

【参考方案10】:

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

【讨论】:

【参考方案11】:

以下对我使用收藏包有用:

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];
                        );
                      );
                )
              ],

【讨论】:

以上是关于遍历列表以在 Flutter 中呈现多个小部件?的主要内容,如果未能解决你的问题,请参考以下文章

传递正确的上下文以在flutter中构建按钮小部件

如何根据列表中的数据在颤动中渲染多个小部件?

Flipswitch小部件呈现为外部面板小部件中的下拉列表

Flutter/Dart:我的小部件树中可以有多个带有状态的小部件吗?

如何从 Firebase Firestore 获取数据并将其存储在列表中以在颤振小部件中使用?

动画列表多个小部件使用相同的 GlobalKey