简体   繁体   中英

Dynamically generate widgets in Flutter

I am trying to dynamically generate a set of widgets based on a particular condition. In this case I am trying to generate a list of RadioTiles

This is how I am trying to generate

  List _listings = new List();

  Widget _getListings() {
    // TODO this will accept json objects in order to display the data
    List listings = new List();
    int i = 0;
    for (i = 0; i < 5; i++) {
      listings.add(
        new RadioListTile<SingingCharacter>(
          title: const Text('Lafayette'),
          value: SingingCharacter.lafayette,
          groupValue: _character,
          onChanged: (SingingCharacter value) {
            setState(() {
              _character = value;
            });
          },
        ),
      );
    }
//     return listings;
  }

and I am trying to display this within a stateful widget like this :

 return new SafeArea(
        child: Column(children: <Widget>[
      new Padding(
        padding: const EdgeInsets.all(20.0),
        child: new Text(
          "Verify and Select a Single Listing?",
          style: _textStyle,
        ),
      ),
      ListView(
        shrinkWrap: true,
        padding: const EdgeInsets.all(20.0),
        children: <Widget>[
          _getListings(),
        ],
      ),
    ]));

The issue is that the value of listings is null due to which I am unable to display any widgets on the screen.

Any insights would be useful.

Thanks,

Edit :

If I do try to return a list this is what I see: 在此处输入图片说明

I am not sure if this is the best way to dynamically create widgets.

Here are some updates to your code:

      Widget build(BuildContext context) {

    return Scaffold(body: SafeArea(
        child: Container(child: Column(children: <Widget>[
          Padding(
            padding: const EdgeInsets.all(20.0),
            child: Text("Verify and Select a Single Listing?",),
          ),
          Expanded(child:  ListView(
            padding: const EdgeInsets.all(20.0),
            children: _getListings(), // <<<<< Note this change for the return type
          ),
          )
        ])
        )));
  }

  List _listings = new List();

  List<Widget> _getListings() { // <<<<< Note this change for the return type
    List listings = List<Widget>();
    int i = 0;
    for (i = 0; i < 5; i++) {
      listings.add(
        RadioListTile<String>(
          title: const Text('Lafayette'),
          value: "c",
          groupValue: "x",
          onChanged: (_) {

          },
        ),
      );
    }
     return listings;
  }

Some things to consider above:

I've made changes to make the code in order to compile and be used for this answer.

  • added comments for notable changes
  • List _listings is unused
  • you can also drop the new keyword when creating new objects (the new version of dart is able to handle this)

Result:

在此处输入图片说明

Some comments on the previous answer;

  • Please do not use unnecessary Containers, if a Container only has a child and nothing else, remove it.
  • The new keyword does not have to be used, Dart linters even tell not to use it. Like here..

Also if your list does not change you could use a List.unmodifiable like in the example below.

final List<Widget> widgets = List.unmodifiable(() sync* {
  for (int i = 0; i < 5; i++) {
    yield RadioListTile<String>(
      title: const Text('Lafayette'),
      value: "c",
      groupValue: "x",
      onChanged: (_) {

      },
    );
  }
}());

This can be used to avoid unnecessary for loop . Doing the same thing in 2 lines

int numberOfWidgets = 5;
List<Widget> listings = List<Widget>.filled(numberOfWidgets, buildWidget());

This will make a list with exact number of widgets. Also, this is only helpful if you want similar type of widget in a list

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM