Home > Software engineering >  Flutter: Populate listview with headers and items from complex list
Flutter: Populate listview with headers and items from complex list

Time:02-17

I have following List:

[
    {
        "ID": "1",
        "ParentID": "0",
        "CategoryName": "FourWheeler",
        "Children": [
        {
            "ID": "9",
            "ParentID": "1",
            "CategoryName": "Jeep",
            "ParentCategoryName": "FourWheeler"
        },
        {
            "ID": "10",
            "ParentID": "1",
            "CategoryName": "Taxi",
            "ParentCategoryName": "FourWheeler"
        },
        {
            "ID": "11",
            "ParentID": "1",
            "CategoryName": "Car",
            "ParentCategoryName": "FourWheeler"
        },
        {
            "ID": "12",
            "ParentID": "1",
            "CategoryName": "Van",
            "ParentCategoryName": "FourWheeler"
        },
        {
            "ID": "13",
            "ParentID": "1",
            "CategoryName": "Other",
            "ParentCategoryName": "FourWheeler"
        }]
    },
    {
        "ID": "2",
        "ParentID": "0",
        "CategoryName": "Boat",
        "Children": [
        {
            "ID": "14",
            "ParentID": "2",
            "CategoryName": "Motorboat",
            "ParentCategoryName": "Boat"
        },
        {
            "ID": "15",
            "ParentID": "2",
            "CategoryName": "Sailingboat",
            "ParentCategoryName": "Boat"
        },
        {
            "ID": "16",
            "ParentID": "2",
            "CategoryName": "SteamBoat",
            "ParentCategoryName": "Boat"
        },
        {
            "ID": "17",
            "ParentID": "2",
            "CategoryName": "Other",
            "ParentCategoryName": "Boat"
        }]
    }
]

I need to populate ListView on the basis of this list. We should have listview populated such a way that there are headers and each headers will have their respective items. For Example, ListView should look something like,

**FourWheeler**
   Jeep
   Taxi
   Car
   Van
   Other
**Boat**
   Motorboat
   Sailingboat
   Steamboat
   Other

For simple list like this:

List Fruits = ['Apple','Orange','Kiwi','Avocado'];

I would have done like this

Fruits.map<Widget>((fruit)=>Container(child: Text(fruit))).toList();

But I don't know how to deal with the scenario I have. Any help will be appreciated. Thanks

CodePudding user response:

This is one way you can populate a ListView as you have described:

import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        body: ListView(
          children: [
            for (final header in data) ...[
              ListTile(title: Text('**${header['CategoryName']}**')),
              for (final item in header['Children'] ?? [])
                ListTile(title: Text('   ${item['CategoryName']}')),
            ],
          ],
        ),
      ),
    );
  }
}

const List<Map<String, dynamic>> data = [
  {
    "ID": "1",
    "ParentID": "0",
    "CategoryName": "FourWheeler",
    "Children": [
      {
        "ID": "9",
        "ParentID": "1",
        "CategoryName": "Jeep",
        "ParentCategoryName": "FourWheeler"
      },
      {
        "ID": "10",
        "ParentID": "1",
        "CategoryName": "Taxi",
        "ParentCategoryName": "FourWheeler"
      },
      {
        "ID": "11",
        "ParentID": "1",
        "CategoryName": "Car",
        "ParentCategoryName": "FourWheeler"
      },
      {
        "ID": "12",
        "ParentID": "1",
        "CategoryName": "Van",
        "ParentCategoryName": "FourWheeler"
      },
      {
        "ID": "13",
        "ParentID": "1",
        "CategoryName": "Other",
        "ParentCategoryName": "FourWheeler"
      }
    ]
  },
  {
    "ID": "2",
    "ParentID": "0",
    "CategoryName": "Boat",
    "Children": [
      {
        "ID": "14",
        "ParentID": "2",
        "CategoryName": "Motorboat",
        "ParentCategoryName": "Boat"
      },
      {
        "ID": "15",
        "ParentID": "2",
        "CategoryName": "Sailingboat",
        "ParentCategoryName": "Boat"
      },
      {
        "ID": "16",
        "ParentID": "2",
        "CategoryName": "SteamBoat",
        "ParentCategoryName": "Boat"
      },
      {
        "ID": "17",
        "ParentID": "2",
        "CategoryName": "Other",
        "ParentCategoryName": "Boat"
      }
    ]
  }
];

You could also group each header with something like an ExpansionTile:

ListView(
  children: [
    for (final header in data)
      ExpansionTile(
        title: Text('**${header['CategoryName']}**'),
        children: [
          for (final item in header['Children'] ?? [])
            ListTile(title: Text('   ${item['CategoryName']}')),
        ],
      ),
  ],
),
  • Related