【问题标题】:How to dynamically append to the children of a Column widget in Flutter如何在 Flutter 中动态附加到 Column 小部件的子级
【发布时间】:2018-11-13 06:14:25
【问题描述】:

Flutter 是一个相当新的框架,因此对简单任务没有太多帮助。我要特别问的是如何将 Card 小部件添加到 Column 小部件。下面提供了源代码以帮助解释我的意思。

假设我有一个创建新卡片的函数,如下所示:

buildRow(barcode, letter, name, price) {
  return new Card(
    child: new Column(
      crossAxisAlignment: CrossAxisAlignment.stretch,
      children: <Widget>[
        new ListTile(
          leading: new CircleAvatar(
            child: new Text(letter),
          ),
          title: new Text(name),
          subtitle: new Text("\$" + price),
          trailing: new Text(
            "x1",
            style: new TextStyle(color: Colors.lightBlue),
            textScaleFactor: 1.2,
          ),
        ),
      ],
    ),
  );
}
var snack = buildRow("091918229292", "C", "Crackers", "\$4.00");
var fruit = buildRow("091928229292", "P", "Pomegranate", "\$2.00");
var juice = buildRow("091948229292", "K", "Kiwi Juice", "\$20.00");

我有以下屏幕/页面:

class Home extends StatefulWidget {
  @override
  HomePage createState() => new HomePage();
}

class HomePage extends State<Home> {
  @override
  Widget build(BuildContext context) {
    return new Column(children: <Widget>[

    ]);
  }
}

假设提供的所有代码都在同一个文件中。如何在主屏幕的列小部件的子项中添加“零食”、“水果”和“果汁”?

【问题讨论】:

    标签: android oop widget flutter


    【解决方案1】:

    如果您手动更新源,这是一个基本示例。

          Column(
            children: _createChildren(),
          )
    

    ///////

    这是创建您提供给列的小部件列表的方法

      List<int> someList = [1, 2, 3, 4, 5];
      List<Widget> _createChildren() {
        return new List<Widget>.generate(someList.length, (int index) {
          return Text(someList[index].toString());
        });
      }
    

    //////

    因此,当您更新列表时,请在 setState 中进行操作

      void _somethingHappens() {
        setState(() {
          someList.add(6);
        });
      }
    

    现在,如果您从流中接收数据,您可以检查StreamBuilder,或者如果它来自Future,您可以使用FutureBuilder

    这个例子也可以在普通的Builder中完成

    【讨论】:

    • 不知何故我需要在 new List&lt;Widget&gt;.generate 之前添加 return 才能使其工作
    • 我遵循了完全相同的步骤。但是设置状态不会更新小部件列表并将其显示在屏幕上。但是,当我单击 android studio 上的热重载时,它确实出现了。 :(请帮忙。
    【解决方案2】:

    好的,我已经解决了我的问题,我所做的是创建一个新列表,如下所示:

    List<Widget> v = [];
    

    并像这样列出身体的孩子:

    class HomePage extends State<Home> {
      @override
      Widget build(BuildContext context) {
        return new Column(children: v);
      }
    }
    

    之后我创建了一个像这样追加的函数:

    buildRow(barcode, letter, name, price) {
      v.add(new Card(
        child: new Column(
          crossAxisAlignment: CrossAxisAlignment.stretch,
          children: <Widget>[
            new ListTile(
              leading: new CircleAvatar(
                child: new Text(letter),
              ),
              title: new Text(name),
              subtitle: new Text("\$" + price),
              trailing: new Text(
                "x1",
                style: new TextStyle(color: Colors.lightBlue),
                textScaleFactor: 1.2,
              ),
            ),
          ], 
        ),
      ));
    }
    

    最后我使用 setState 函数将更改应用到屏幕。

    【讨论】:

    • 您好,我想知道如何删除特定的小部件。我知道方法是 _list.remove();但是我如何定位特定的小部件?
    • 您可以使用映射,其中键是字符串,值是小部件。地图值将在小部件树中使用。话虽如此,删除一个小部件相当于从地图中删除一个键值对并运行 setState
    【解决方案3】:

    在列中,您可以像这样通过地图添加子项:

    Column(
      children: List<Widget>.generate(length, (index) {
        return Container(
          child: Text('$index')
        );
      })
    )
    

    【讨论】:

      【解决方案4】:
      class SearchCat extends StatelessWidget {
        final List<Widget> list;
        final ValueChanged onChange;
      
        SearchCat({this.list, this.onChange}): super();
        @override
        Widget build(BuildContext context) {
          return Container(
            child: Row(
              children: list.map((v) {
                return Container(
                  child: v,
                  decoration: BoxDecoration(
                    borderRadius: BorderRadius.circular(57.0),
                    border: Border.all(width: 1.0, color: const Color(0xff707070)),
                  ),
                );
              }).toList()
            )
          );
        }
      }
      

      我们可以使用 List.map 来填充小部件列表。

      这里是如何使用它的示例。

      class MyWidget extends StatelessWidget {
        @override
        Widget build(BuildContext context) {
          return SearchCat(list: [
              Text('Hello, World!', style: Theme.of(context).textTheme.headline4),
              Text('Hello, World!', style: Theme.of(context).textTheme.headline4),
              Text('Hello, World!', style: Theme.of(context).textTheme.headline4),
            ]
          );
        }
      }
      

      您可以将其粘贴到 (Flutter Dartpad

      【讨论】:

      • 虽然这段代码可以解决问题,但including an explanation 确实有助于提高帖子的质量。请记住,您是在为将来的读者回答问题,而这些人可能不知道您提出代码建议的原因
      【解决方案5】:

      你应该可以做这样的事情:

      class HomePage extends State<Home> {
        @override
        Widget build(BuildContext context) {
          return new Column(children: <Widget>[
             buildRow("091918229292", "C", "Crackers", "\$4.00"),
             buildRow("091928229292", "P", "Pomegranate", "\$2.00"),
             buildRow("091948229292", "K", "Kiwi Juice", "\$20.00"),
          ]);
        }
      } 
      

      如果你真的想保留你可以做的参考:

      class HomePage extends State<Home> {
        var snack;
        var fruit;
        var juice;
      
        @override
        void initState() {
          super.initState();
      
          snack = buildRow("091918229292", "C", "Crackers", "\$4.00");
          fruit = buildRow("091928229292", "P", "Pomegranate", "\$2.00");
          juice = buildRow("091948229292", "K", "Kiwi Juice", "\$20.00");
        }
      
        @override
        Widget build(BuildContext context) {
          return new Column(children: <Widget>[
            snack, 
            fruit, 
            juice,
          ]);
        }
      } 
      

      【讨论】:

      • 这是将卡片静态放置到主屏幕(它发生在主屏幕实例化时)。我想要一个功能,这样如果我要获得一个新项目附加到主屏幕(在主屏幕已经被实例化之后)我可以很容易地做到这一点。 FutureBuilder 类可能是相关的。
      • 啊,不清楚。好吧,我想这取决于您如何获取数据。您可以使用 FutureBuilder 或 StreamBuilder。 StreamBuilder 将允许您通过从源推送来更新 UI
      猜你喜欢
      • 2021-03-08
      • 2019-01-07
      • 2020-04-16
      • 1970-01-01
      • 2020-09-29
      • 2020-04-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多