the element type 'List<widget>' can't be assigned to the list type 'Widget'

AndroidIosFlutter

Android Problem Overview


I am trying to add data using for loop in gridview but it is showing some error. Here is my code for component

return new GridView.count(
    crossAxisCount: 2,
    padding: const EdgeInsets.all(10.0),
    crossAxisSpacing: 10.0,
    mainAxisSpacing: 10.0,
    children: <Widget>[getList()],
);

getList() code

List<Widget> getList() {
  List<Widget> childs = [];
  for (var i = 0; i < 10; i++) {
    childs.add(new ListItem('abcd ' + $i));
  }
  return childs;
}

But it is showing compile time error.

The element type 'List<widget>' can't be assigned to the list type 'Widget'

Android Solutions


Solution 1 - Android

Here you are wrapping a list as list

children: <Widget>[getList()],

This should rather be

children: getList(),

Solution 2 - Android

Just use spread operator:

return new GridView.count(
    crossAxisCount: 2,
    padding: const EdgeInsets.all(10.0),
    crossAxisSpacing: 10.0,
    mainAxisSpacing: 10.0,
    children: <Widget>[...getList()],
);

Solution 3 - Android

Using the spread operator is one way of solving this issue. But there is also another one that involves the use of toList() method.

children property requires list of Widgets. However, in your case, it becomes the following:

return new GridView.count(
    crossAxisCount: 2,
    padding: const EdgeInsets.all(10.0),
    crossAxisSpacing: 10.0,
    mainAxisSpacing: 10.0,
    children: [
      [
        ListItem('abcd 0'),
        ListItem('abcd 1'),
        ...
      ]
    ],
);

Therefore,

Solution 1

the wrapping should be children: getList(),

Solution 2 (spread operator)

children: <Widget>[...getList()],

As a side note, you might encounter this issue when trying to use something like a map() method. In that case, the usage of toList() method comes in handy. For example,

children: someListOfObjects.map((el) => Text(el)).toList(),

Solution 4 - Android

Since the answer was not satisfactory for me, so I found another solution.

Flutter gives you the possibility to write conditions on a single line also in the graphic, so you can insert a cycle on a single line and then insert the other different widgets. This is a practical example in response to the main question:

 Column(
    children: <Widget>
      [
        for (int i = 0;
        i < workouts.series.length;
        i++)
          "//CREATE N YOUR WIDGETS//",
          new Text(
          "${workouts.series.length} x ${exerciseWorkout.repsToDo} ",
          style: TextStyle(
          color: Colors.black87,
          fontSize: 16,
          fontWeight: FontWeight.bold),
          )
      ],
     )

Solution 5 - Android

There are two methods I found working.

Method 1 - Simple

This method is supported in the latest version of flutter

var list = ["one", "two", "three", "four"]; 

child: Column(
      mainAxisAlignment: MainAxisAlignment.center,
      children: <Widget>[
          for(var item in list ) Text(item)
      ],
),

Method 2 - A bit Complex

Tested in Flutter 1.12.13+hotfix.7 and Dart 2.7.0, we can iterate over the list of objects as follows:

Iterate over the list of objects

...data.map((f) => paragraph(f.title, f.description)).toList(),

Custom widget

Column paragraph(String title, String description) {
  return new Column(
    children: <Widget>[
      Container(
        child: Text(title),
      ),
      Container(
        child: Text(description),
      ),
    ],
  );
}

Data: List of objects

List<AboutUsData> data = [
    new AboutUsData(
      title: 'Our Vision',
      description:
          'OUR VISION',
    ),
    new AboutUsData(
      title: 'Our Mission',
      description:
          'OUR MISSION',
    ),
    new AboutUsData(
      title: 'Our Values',
      description:
          'As we grow as a company',
    ),
  ];

Solution 6 - Android

I have the same problem, i have a list of:

List<Info> li = [
    Info(name: "oussama", height: 180, date: DateTime.now()),
    Info(name: "mehdy", height: 150, date: DateTime.utc(1997, 05, 14)),
    Info(name: "ahmed", height: 190, date: DateTime.utc(1997, 04, 11)),
    Info(name: "sofiene", height: 160, date: DateTime.utc(1995, 07, 13)),
    Info(name: "mohamed", height: 150, date: DateTime.utc(1994, 01, 17))
];

and i want it to display them in a column which return a list<Widget> so i followed the same as sad @Günter Zöchbauer: i created a function getList():

List<Widget> getList() {
    List<Widget> childs = li
        .map((e) => Row(children: <Widget>[
              Text(e.name, style: const TextStyle(fontSize: 25)),
              Text("${e.height}", style: const TextStyle(fontSize: 25)),
              Text("${e.date}", style: const TextStyle(fontSize: 25))
            ]))
        .toList();
    return childs;
  }

then i assigned it to Column:

body: Container(
 child: Column(
   children: getList()
))

it worked for me :)

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionRaviView Question on Stackoverflow
Solution 1 - AndroidGünter ZöchbauerView Answer on Stackoverflow
Solution 2 - AndroidDarek AdamkiewiczView Answer on Stackoverflow
Solution 3 - AndroidTaiyr BegeyevView Answer on Stackoverflow
Solution 4 - AndroidAlexPadView Answer on Stackoverflow
Solution 5 - AndroidWasiFView Answer on Stackoverflow
Solution 6 - Androidoussama ben hassenView Answer on Stackoverflow