web-dev-qa-db-ja.com

Flutterで列ウィジェットの子に動的に追加する方法

Flutterはごく最近のフレームワークであり、単純なタスクについてはあまり支援がありません。私が特に求めているのは、カードウィジェットを列ウィジェットに追加する方法です。以下にソースコードを示します。これは、私の意味を説明するのに役立ちます。

以下に示すように、新しいカードを作成する関数があるとします。

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>[

    ]);
  }
}

提供されたすべてのコードが同じファイル内にあるとしましょう。ホーム画面の列ウィジェットの子に「スナック」、「フルーツ」、「ジュース」を追加するにはどうすればよいですか?

6
Questionare232

問題を解決しました。次のように新しいリストを作成しました。

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関数を使用して変更を画面に適用しました。

1
Questionare232

これは、ソースを手動で更新する場合の基本的な例です。

      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でも実行できます。

7
Tree

次のようなことができるはずです。

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