4

I've got a 2x2 grid that I am trying to populate with cards, where each card is of a specific style. Each card has a title and a route which when clicked opens another page (route). I'd like to specify the "name" of the card and the "name of the page" which the the click should lead to for each "name" in an index of "names".

The problem is 1. I'm not sure how to do the for-each loop within the widget. 2. Not sure how to make this work for more than 1 parameter being; name of card and name of new page.

I have already tried a few options, 2 of which are shown below.

class SubjectsPage extends StatefulWidget {

  @override
  _SubjectsPageState createState() => new _SubjectsPageState();
}

class _SubjectsPageState extends State<SubjectsPage> with TickerProviderStateMixin {

  @override
  Widget build(BuildContext context) {
    var names = ["one", "two", "three", "four"];
        return new Material(     
          child: new Container(
            child: new Center(
              child: GridView.count(
                crossAxisCount: 2,
                padding: EdgeInsets.fromLTRB(16.0, 128.0, 16.0, 16.0),
                childAspectRatio: 8.0 / 8.5,
                children: <Widget>[

                  //option 1
                  names.forEach((unit) => Cards(unit: unit,)),

                  //option 2
                  for (var i = 0; i < names.length; i++) {
                    Cards(unit: names[i])
                  }

            ],
          ), 
        ),
      ),
    );
  }
}

The error for option 1 is that "the expression here has a type of 'void', and therefore cannot be used."

The error for option 2 is that "the element type 'Set' can't be assigned to the list type 'Widget'."

1 Answer 1

4

Yes, you cannot use forEach but map. You can map strings to widget using map method.

Example:

class SubjectsPage extends StatefulWidget {
  @override
  _SubjectsPageState createState() => new _SubjectsPageState();
}

class _SubjectsPageState extends State<SubjectsPage>
    with TickerProviderStateMixin {
  @override
  Widget build(BuildContext context) {
    var names = ["one", "two", "three", "four"];
    return Material(
      child: Container(
        child: Center(
          child: GridView.count(
            crossAxisCount: 2,
            padding: EdgeInsets.fromLTRB(16.0, 128.0, 16.0, 16.0),
            childAspectRatio: 8.0 / 8.5,
            children: names.map((String name) {
              return Cards(unit: name);
            }).toList(),
          ),
        ),
      ),
    );
  }
}

Or: Your option two can be done like

class SubjectsPage extends StatefulWidget {
  @override
  _SubjectsPageState createState() => new _SubjectsPageState();
}

class _SubjectsPageState extends State<SubjectsPage>
    with TickerProviderStateMixin {
  @override
  Widget build(BuildContext context) {
    var names = ["one", "two", "three", "four"];
    return Material(
      child: Container(
        child: Center(
          child: GridView.count(
            crossAxisCount: 2,
            padding: EdgeInsets.fromLTRB(16.0, 128.0, 16.0, 16.0),
            childAspectRatio: 8.0 / 8.5,
            children: [
                for(String name in names) Cards(unit:name)
            ],
          ),
        ),
      ),
    );
  }
}

Hope that helps!

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

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.