Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dynamically generate widgets in Flutter

Tags:

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

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

like image 663
bhavs Avatar asked Mar 18 '19 07:03

bhavs


People also ask

Which type of widget is based for dynamic data?

Flutter is based on widgets.

How do you display data dynamically in Flutter?

We can use ListView. builder(..) in Stateless Widgets if we want to display dynamic (different) contents every time the widget is loaded within an application. With Stateful widgets, it can change the contents of the screen dynamically.


3 Answers

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

like image 106
Durdu Avatar answered Oct 04 '22 11:10

Durdu


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

      },
    );
  }
}());
like image 27
Daniel.roek Avatar answered Sep 30 '22 11:09

Daniel.roek


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

like image 39
Rakesh Ranjan Avatar answered Oct 01 '22 11:10

Rakesh Ranjan