11

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: enter image description here

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

3
  • 1
    Why did you comment out return listings;? Why did you add List _listings = new List();? It doesn't look like it's used. Commented Mar 18, 2019 at 7:40
  • I would be returning the List<Widget> then and I want the list to be displayed in a scrollable widget and a List<Widget> cannot be assigned to the widget. I am really not sure if this is the best way to create a dynamic number of Widgets. Commented Mar 18, 2019 at 7:53
  • "and a List<Widget> cannot be assigned to the widget." I don't understand why this would cause problems in your example. Commented Mar 18, 2019 at 7:56

3 Answers 3

15

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:

enter image description here

Sign up to request clarification or add additional context in comments.

1 Comment

Widget _getListing() needs to be used if streambuilder generates the list. I need a more generic solution using Widget like the author originally proposed. return StreamBuilder<List<MyClass>>(...)
1

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: (_) {

      },
    );
  }
}());

Comments

0

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.