Search code examples
flutterdartdictionarylistviewgroup-by

Flutter ExpansionTile with map using groupBy in list


I'm trying to make the ExpansionTile widget works with a map created from a List. Here is what my code looks like:

  class School{
  final String classname;
  final String section;
  final String alumnNumber;

  School({required this.classname, required this.section, required this.alumnNumber}); }

  final List<School> schoolList =
  [ 
    School(classname: "test1", section: "A", alumnNumber: 20),
    School(classname: "test2", section: "B", alumnNumber: 10),    
    School(classname: "test3", section: "C", alumnNumber: 15),
    School(classname: "test4", section: "B", alumnNumber: 16),
    School(classname: "test5", section: "A", alumnNumber: 22),
    School(classname: "test6", section: "D", alumnNumber: 25),
    School(classname: "test7", section: "A", alumnNumber: 24),
    School(classname: "test8", section: "A", alumnNumber: 21),
  ]

This will be my starting point. I want to regroup this list so items with same 'section' would be collapsed together.

final sectionGroup =groupBy(schoolList, (obj) => (obj as School).section);

If I try to print my sectionGroup it seems to work

{A: [Instance of 'School',Instance of 'School',Instance of 'School',Instance of 'School'], B: [Instance of 'School',Instance of 'School'], C: [Instance of 'School'], D: [Instance of 'School']}

What I want to do is to show this in an ExpansionTile Widget but nothing seems to work. How can I accomplish that?


Solution

  • sectionGroup is providing map with section and List<School>.

    You can iterate the map/values like

    final sectionGroup = groupBy(schoolList, (obj) => (obj as School).section);
    
    class GExpMar extends StatelessWidget {
      const GExpMar({super.key});
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          body: ListView.builder(
            itemCount: sectionGroup.length,
            itemBuilder: (context, index) {
              final key = sectionGroup.keys.elementAt(index);
              final values = sectionGroup.values.elementAt(index);
              return ExpansionTile(
                title: Text("$key"),
                children: values
                    .map(
                      (e) => ListTile(
                        // you can use Column or other widget
                        title: Text("${e.classname}"),
                        subtitle: Text("${e.alumnNumber}"),
                      ),
                    )
                    .toList(),
              );
            },
          ),
        );
      }
    }