I'm having some trouble with state for a list of items. I want to save state for each item, as well as some state for the entire list. Any thoughts or guidance for my implementation? Errors marked with "###". Thanks. Also, how do I format a pasted-in set of code lines? ctrl-K just blew them away, and adding pre/code tags still gets a red complaint. I just added 4 spaces to each line to get it to work.

class TruffleListScreenList extends StatefulWidget {
  @override
  TruffleListScreenListState createState() {
    return TruffleListScreenListState();
  }
}

class TruffleListScreenListState extends State<TruffleListScreenList> {
  List<TruffleItemState> truffleItems = [
    TruffleItemState("chocolate", "images/IMG_1252.JPG"),
    TruffleItemState("mint", "images/IMG_1253.JPG"),
    TruffleItemState("tooti-frutti", "images/IMG_1254.JPG"),
    TruffleItemState("peanut butter", "images/IMG_1255.JPG"),
  ];

  @override
  Widget build(BuildContext context) {
    return ListView(
      children: truffleItems,   ### The argument type 'List TruffleItemState' can't be assigned to the parameter type 'List Widget'
    );
  }
}

class TruffleItem extends StatefulWidget {
  @override
  TruffleItemState createState() {
    return TruffleItemState();   ### 2 required argument(s) expected, but 0 found.
  }
}

class TruffleItemState extends State<TruffleItem> {
  String name;
  String imageFile;
  int qty;
  bool add;

  TruffleItemState(this.name, this.imageFile);

  @override
  Widget build(BuildContext context) {  // build a row of stuff as a list item
    return Row(

    );
  }
}


Solution 1: George

The structure for the Widgets looks good: one for the list, one for each list item.

The next step is to make a list of Widgets for each TruffleItem and use that in the children for the ListView. To achieve that, you'll want to use the map function on the List class. Also, you have to pass the parameters twice, as of my experience. Once for the StatefulWidget, then replicate to the State.

Your code should look like this:

class TruffleListScreenList extends StatefulWidget {
  @override
  TruffleListScreenListState createState() {
    return TruffleListScreenListState();
  }
}

class TruffleListScreenListState extends State<TruffleListScreenList> {
  List<TruffleItemState> truffleItems = [
    TruffleItemState("chocolate", "images/IMG_1252.JPG"),
    TruffleItemState("mint", "images/IMG_1253.JPG"),
    TruffleItemState("tooti-frutti", "images/IMG_1254.JPG"),
    TruffleItemState("peanut butter", "images/IMG_1255.JPG"),
  ];

  @override
  Widget build(BuildContext context) {
    return ListView(
        // Map each item to a widget, then turn into a list.
        children: truffleItems.map((item) => TruffleItem(item.name, item.imageFile)).toList(),
    );
  }
}

class TruffleItem extends StatefulWidget {
  final String name;
  final String imageFile;

  TruffleItem(this.name, this.imageFile);

  @override
  TruffleItemState createState() {
    return TruffleItemState();
  }
}

class TruffleItemState extends State<TruffleItem> {
  int qty;
  bool add;

  TruffleItemState();

  @override
  Widget build(BuildContext context) {  // build a row of stuff as a list item
    return Row(
        // Use the variables like widget.name or widget.imageFile
    );
  }
}

As said in the comments by Richard Heap:

"Don't pass the name and imageFile down to TruffleItemState. Instead, you can access them from there as widget.name and widget.imageFile respectively."