skip to Main Content

I have the below list of objects that am trying to make into an expandable list grouped by month. Which is a value in the list.

{
   "status":"Success",
   "payments":[
      {
         "id":291,
         "user":{
            "id":12,
            "userID":"cvWLyHRla",
            "name":"Bill Obama",
            "email":"email@user1",
            "username":"username1",
            "profilePic":null,
            "created_at":"2023-05-08T00:52:11.000000Z"
         },
         "userID":12,
         "groupID":28,
         "paymentDueDate":"2023-11-01",
         "paymentDate":null,
         "amount":1000,
         "forDuration":"November",
         "proofOfPayment":null,
         "paymentMode":null,
         "paymentID":null,
         "paymentToken":null,
         "approvedBy":null,
         "approvedByUser":null,
         "approvedAt":null,
         "created_at":"2023-10-30T07:52:30.000000Z",
         "status":"pending",
         
      },
      {
         "id":290,
         "user":{
            "id":8,
            "userID":"yuwrgojsvIXqGeAzT18bTxbObEG3",
            "name":"Obama Clinton",
            "email":"email@user2",
            "username":"username2",
            "profilePic":"645866b914fu.jpg",
            "created_at":"2023-05-07T23:01:24.000000Z"
         },
         "userID":8,
         "groupID":28,
         "paymentDueDate":"2023-11-01",
         "paymentDate":"2023-10-30",
         "amount":1000,
         "forDuration":"November",
         "proofOfPayment":null,
         "paymentMode":"MobileMoney",
         "paymentID":"5888699-999",
         "paymentToken":null,
         "approvedBy":null,
         "approvedByUser":null,
         "approvedAt":"2023-10-30 07:53:15",
         "created_at":"2023-10-30T07:52:30.000000Z",
         "status":"paid",
         
      }
   ]
}

Am trying to create a flutter expandable list based on the "forDuration". So for each "forDuration" i should have children of the name, email, amount for all Users for that period. I have the below Listview.builder code but it is not showing the expansion tiles.
Please kindly help. Below is what i have tried but the outcome is not as desired.

ListView.builder(
  itemCount: controller.groupPaymentResponse.value?.payments?.length ?? 0,
  itemBuilder: (BuildContext context, int index) {
    var e = controller.groupPaymentResponse.value!.payments![index];
      bool sameforDuration = false;
      if (controller.groupPaymentResponse.value!.payments![index + 1].forDuration ==
        controller.groupPaymentResponse.value!.payments![index]) {
            bool sameforDuration = true;
        }
      var image = e.user!.profilePic == null ? userPlaceHolder : "${e.user!.imagePath}/${e.user!.profilePic}";
      return ExpansionTile(
        title: Text(
          e.forDuration.toString(),
        ),
          children: [Text(e.user!.name!), Text(e.user!.email!), Text(e.amount.toString())],
      );
      }),

2

Answers


  1. I tried quickly reproducing your code, with direct data, and there was no error. Can you provide an example in Dartpad.dev

    Login or Signup to reply.
  2. You need to modify(group) your list to get this result

    You can copy this code and run it in dartpad, I attached output following screenshot

    import 'package:flutter/material.dart';
    import "package:collection/collection.dart";
    
    void main() => runApp(MyApp());
    
    class MyApp extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          title: 'Flutter Demo',
          debugShowCheckedModeBanner: false,
          theme: ThemeData(
            colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
            useMaterial3: true,
          ),
          home: const MyHomePage(title: 'Flutter Demo Home Page'),
        );
      }
    }
    
    class MyHomePage extends StatefulWidget {
      final String title;
    
      const MyHomePage({
        Key? key,
        required this.title,
      }) : super(key: key);
    
      @override
      State<MyHomePage> createState() => _MyHomePageState();
    }
    
    class _MyHomePageState extends State<MyHomePage> {
      late Map<String, List<TestingObj>> groupedItemMap;
    
      List<TestingObj> testingItems = [
        TestingObj(
          "Book",
          "100000",
          "November",
        ),
        TestingObj(
          "Pencil",
          "100",
          "November",
        ),
        TestingObj(
          "Eraser",
          "1000",
          "December",
        ),
        TestingObj(
          "Ruler",
          "100000",
          "September",
        ),
        TestingObj(
          "Bag",
          "100000",
          "September",
        ),
        TestingObj(
          "Paper",
          "100000",
          "September",
        ),
      ];
    
      @override
      void initState() {
        groupedItemMap = groupBy(testingItems, (entry) => entry.month);
    
        print(groupedItemMap.toString());
    
        super.initState();
      }
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          body: ListView.builder(
              itemBuilder: (context, index) => ExpansionTile(
                    title: Text(
                      groupedItemMap.entries.elementAt(index).key,
                    ),
                    children: groupedItemMap.entries
                        .elementAt(index)
                        .value
                        .map((item) => Text(item.itemName))
                        .toList(),
                  ),
              itemCount: groupedItemMap.length),
        );
      }
    }
    
    class TestingObj {
      final String itemName;
      final String profit;
      final String month;
    
      TestingObj(this.itemName, this.profit, this.month);
    }
    

    Result images

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search