How can I iterate over an array of objects which belong to a key value - Flutter

自作多情 提交于 2020-07-03 13:28:32

问题


I have a list of data called anchors that has a link to a detailed screen. And each anchor has distribution centers which are an array of nested objects. so I was able to parse an id of each of the anchors to a detailed screen and Oid I am having a challenge to loop through the children i.e the distribution centers of the anchors. Please can anyone help me, I was able to pull all the values belonging to an anchor to the detailed screen but how to loop through the nested values in the detailed screen is the problem. the nested values are DistributionCentres in the array below. please can anyone help me still learning more on flutter?

json array:

{
 "Anchors": [
    {
      "Oid": 11,
      "Name": "MAIZE ASSOCIATION OF NIGERIA",
      "Acronym": "MAAN",
      "DistributionCentres": [
        {
          "Oid": 11,
          "Name": "Logo Centre (Zone A)",
          "Address": "Private Warehouse, Ugba, Logo LGA"
        },
        {
          "Oid": 12,
          "Name": "Makurdi Centre (Zone B)",
          "Address": "Ministry of Agric, Makurdi "
        },
        {
          "Oid": 13,
          "Name": "Oturkpo Centre (Zone C)",
          "Address": "Private Warehouse, Oturkpo"
        },
        {
          "Oid": 15,
          "Name": "Borno MAAN centre",
          "Address": "Bolori Store, Flavour Mill, Behind Vita Foam, Maiduguri"
        },
        {
          "Oid": 18,
          "Name": "Bauchi Centre",
          "Address": "BASPD, Dass Road, Bauchi"
        }
      ],
      "NoOfDistributionCentres": 5
    },
    {
      "Oid": 2,
      "Name": "MAIZE GROWERS, PROCESSORS AND MARKETERS ASSOCIATION OF NIGERIA",
      "Acronym": "MAGPAMAN",
      "DistributionCentres": [
        {
          "Oid": 2,
          "Name": "Guma Centre",
          "Address": "P 32, 2nd Avenue Federal Housing Estate, N/Bank, Makurdi"
        },
        {
          "Oid": 3,
          "Name": "Logo Centre",
          "Address": "Terhemen Akema Storage Facility, Ugba, Logo LGA"
        },
        {
          "Oid": 5,
          "Name": "Oturkpo Centre",
          "Address": "Grain Store, Lower Benue Okele Project, Otukpo"
        },
        {
          "Oid": 6,
          "Name": "Gboko Centre",
          "Address": "K3 New Road, Opposite former coca cola plant. Solar Schools Street, Gboko"
        },
        {
          "Oid": 7,
          "Name": "Gwer East Centre",
          "Address": "Ahua Shardye's Warehouse, Behind Sylkan Filling Station, Ikpayongo , G/East LGA"
        },
        {
          "Oid": 8,
          "Name": "Kwande Centre",
          "Address": "KM 3, Adagi Road, Adikpo"
        },
        {
          "Oid": 9,
          "Name": "Ohimini Centre",
          "Address": "Ajoga Oglewu, Ohimini"
        },
        {
          "Oid": 10,
          "Name": "Oju Centre",
          "Address": "Behind Town Hall, Ohuhu owo, Oju LGA"
        }
      ],
      "NoOfDistributionCentres": 8
    }
  ],
}

Anchors page with a link to the detailed screen:

import 'package:erg_app/AnchorDetails.dart';
import 'package:erg_app/Details.dart';
import 'package:erg_app/StockPage.dart';
import 'package:flutter/material.dart';
import 'package:erg_app/Widgets/nav-drawer.dart';
import 'dart:convert';
import 'package:shared_preferences/shared_preferences.dart';

void main() => runApp(MaterialApp(
      home: AnchorsPage(),
    ));

class AnchorsPage extends StatefulWidget {
  @override
  _MyHomeState createState() => _MyHomeState();
}

class _MyHomeState extends State<AnchorsPage> {
  var user;
  var userData;
  List <dynamic> anchors = [];
  @override
  void initState() {
    _getUserAnchor();
    super.initState();
  }

  _getUserAnchor() async {
    SharedPreferences localStorage = await SharedPreferences.getInstance();
    var userJson = localStorage.getString('loginRes');
    user = json.decode(userJson);
    setState(() {
      anchors = user['Anchors'];
    });
    print(anchors);
    setState(() {
      userData = anchors;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      drawer: NavDrawer(),
      appBar: AppBar(
        title: Text('Anchors Details'),
        iconTheme: IconThemeData(color: Colors.white),
        backgroundColor: Colors.green,
      ),
      body: Container(
        padding: const EdgeInsets.fromLTRB(10, 30, 10, 10),
        child: ListView(
          children: <Widget>[
            Row(
              mainAxisAlignment: MainAxisAlignment.spaceAround,
              children: <Widget>[
                Icon(Icons.card_membership,
                    size: 35, color: Colors.orange[400]),
                Text(
                  'Assigned Anchors',
                  style: TextStyle(color: Colors.orange[400], fontSize: 25),
                ),
              ],
            ),
            ListView.builder(
                shrinkWrap: true,
                itemCount: anchors.length,
                physics: NeverScrollableScrollPhysics(),
                itemBuilder: (BuildContext context, int i) {
                  return Padding(
                    padding: const EdgeInsets.all(10.0),
                    ////////////// 1st card///////////

                    child: Card(
                      elevation: 4.0,
                      color: Colors.grey[100],
                      margin: EdgeInsets.only(
                          left: 10, right: 10, top: 20, bottom: 10),
                      shape: RoundedRectangleBorder(
                          borderRadius: BorderRadius.circular(10)),
                      child: Container(
                        padding: EdgeInsets.only(left: 15, top: 20, bottom: 10),
                        width: MediaQuery.of(context).size.width,
                        child: Column(
                          crossAxisAlignment: CrossAxisAlignment.start,
                          children: <Widget>[
                            Row(
                              children: <Widget>[
                                Padding(
                                  padding: const EdgeInsets.all(8.0),
                                  child: Container(
                                      width: 50.0,
                                      height: 50.0,
                                      decoration: new BoxDecoration(
                                          shape: BoxShape.circle,
                                          image: new DecorationImage(
                                              fit: BoxFit.cover,
                                              image: AssetImage(
                                                  'assets/images/user.png')))),
                                ),
                                SizedBox(
                                  width: 20,
                                ),
                                Text(
                                  anchors[i]['Acronym'],
                                  textAlign: TextAlign.center,
                                  style: TextStyle(
                                    color: Color(0xFF9b9b9b),
                                    fontSize: 20,
                                    decoration: TextDecoration.none,
                                    fontWeight: FontWeight.normal,
                                  ),
                                ),
                              ],
                            ),
                            Container(width: 10),
                            Row(
                              children: <Widget>[
                                Padding(
                                  padding:
                                      const EdgeInsets.only(left: 10, top: 10),
                                  child: Text(
                                    'Allocated Farmers:',
                                    textAlign: TextAlign.left,
                                    style: TextStyle(
                                      color: Color(0xFF9b9b9b),
                                      fontSize: 14.0,
                                      decoration: TextDecoration.none,
                                      fontWeight: FontWeight.normal,
                                    ),
                                  ),
                                ),
                                Padding(
                                  padding:
                                      const EdgeInsets.only(left: 70, top: 12),
                                  child: Text(
                                    anchors[i]['Oid'].toString(),
                                    textAlign: TextAlign.left,
                                    style: TextStyle(
                                      color: Colors.grey[700],
                                      fontSize: 14.0,
                                      decoration: TextDecoration.none,
                                      fontWeight: FontWeight.normal,
                                    ),
                                  ),
                                ),
                              ],
                            ),
                            
                            
                            Container(
                              height: 20,
                            ),
                            Row(
                              children: <Widget>[
                                /////////// Buttons /////////////

                                Padding(
                                  padding: const EdgeInsets.all(10.0),
                                  child: FlatButton(
                                          child: Padding(
                                            padding: EdgeInsets.only(
                                                top: 8,
                                                bottom: 8,
                                                left: 10,
                                                right: 8),
                                            child: Text(
                                              'View Details',
                                              textDirection: TextDirection.ltr,
                                              style: TextStyle(
                                                color: Colors.white,
                                                fontSize: 15.0,
                                                decoration: TextDecoration.none,
                                                fontWeight: FontWeight.normal,
                                              ),
                                            ),
                                          ),
                                          color: Colors.blueGrey,
                                          shape: new RoundedRectangleBorder(
                                              borderRadius:
                                                  new BorderRadius.circular(
                                                      20.0)),
                                          onPressed: () {
                                            Navigator.push(
                                                context,
                                                new MaterialPageRoute(
                                                    builder: (context) =>
                                                        detailsPage(value : anchors)));
                                          },
                                        ),
                                ),

                                /////////// End of Buttons /////////////
                              ],
                            ),
                          ],
                        ),
                      ),
                    ),
                  );
                })
          ],
        ),
      ),
    );
  }
}

Detailed Screen:

  import 'package:flutter/material.dart';


class detailsPage extends StatefulWidget {
  dynamic value;
  detailsPage({Key key, @required this.value}) : super(key: key);
  @override
  _detailsPageState createState() => _detailsPageState(value);
}

class _detailsPageState extends State<detailsPage> {

  dynamic value;
  _detailsPageState(this.value);
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("Anchors Details Page"),
        iconTheme: IconThemeData(color: Colors.white),
        backgroundColor: Colors.green,
      ),
      // body: Center(
      //   child: Text(
      //     value[1]['Name'].toString(),
      //   ),
      // ),


       body: Column(
     children: <Widget>[
        Padding(
          padding: const EdgeInsets.all(8.0),
          child: Card(
            child: Column(
              children: <Widget>[
                Text(value[1]['Name']),
                Text(value[1]['Oid'].toString()),
                //Text(value [1]['DistributionCentres']),
              ],
            ),
          ),
        ),
    ],
   ),
    );
  }
}

回答1:


I recommend you to use data classes for such situations.

import 'package:flutter/material.dart';

List<Anchor> _parseAnchors(Map<String, dynamic> map) {
  final anchors = <Anchor>[];
  for (var anchorMap in map['Anchors']) {
    final anchor = Anchor.fromMap(anchorMap);
    anchors.add(anchor);
  }
  return anchors;
}

class Anchor {
  final int oId;
  final String name;
  final String acronym;
  final List<DistributionCenter> distributionCenters;

  const Anchor({
    @required this.oId,
    @required this.name,
    @required this.acronym,
    @required this.distributionCenters,
  });

  factory Anchor.fromMap(Map<String, dynamic> map) {
    final distributionCenters = <DistributionCenter>[];
    for (var distribution in map['DistributionCentres']) {
      final distributionCenter = DistributionCenter.fromMap(distribution);
      distributionCenters.add(distributionCenter);
    }

    return Anchor(
      oId: map['Oid'] as int,
      name: map['Name'] as String,
      acronym: map['Acronym'] as String,
      distributionCenters: distributionCenters,
    );
  }
}

class DistributionCenter {
  final int id;
  final String name;
  final String address;

  const DistributionCenter({
    @required this.id,
    @required this.name,
    @required this.address,
  });

  factory DistributionCenter.fromMap(Map<String, dynamic> map) {
    return DistributionCenter(
      id: map['Oid'] as int,
      name: map['Name'] as String,
      address: map['Address'] as String,
    );
  }
}

class AnchorPage extends StatelessWidget {
  // details page
  final Anchor anchor;

  @override
  const AnchorPage({Key key, @required this.anchor}) : super(key: key);

  Widget build(BuildContext context) {
    return Scaffold(
      body: Container(
        child: Text(anchor.name),
      ),
    );
  }
}

class AnchorsPage extends StatefulWidget {
  const AnchorsPage({Key key}) : super(key: key);

  @override
  _AnchorsPageState createState() => _AnchorsPageState();
}

class _AnchorsPageState extends State<AnchorsPage> {
  static const anchorsMap = {
    "Anchors": [
      {
        "Oid": 11,
        "Name": "MAIZE ASSOCIATION OF NIGERIA",
        "Acronym": "MAAN",
        "DistributionCentres": [
          {
            "Oid": 11,
            "Name": "Logo Centre (Zone A)",
            "Address": "Private Warehouse, Ugba, Logo LGA"
          },
          {
            "Oid": 12,
            "Name": "Makurdi Centre (Zone B)",
            "Address": "Ministry of Agric, Makurdi "
          },
          {
            "Oid": 13,
            "Name": "Oturkpo Centre (Zone C)",
            "Address": "Private Warehouse, Oturkpo"
          },
          {
            "Oid": 15,
            "Name": "Borno MAAN centre",
            "Address": "Bolori Store, Flavour Mill, Behind Vita Foam, Maiduguri"
          },
          {
            "Oid": 18,
            "Name": "Bauchi Centre",
            "Address": "BASPD, Dass Road, Bauchi"
          }
        ],
        "NoOfDistributionCentres": 5
      },
      {
        "Oid": 2,
        "Name":
            "MAIZE GROWERS, PROCESSORS AND MARKETERS ASSOCIATION OF NIGERIA",
        "Acronym": "MAGPAMAN",
        "DistributionCentres": [
          {
            "Oid": 2,
            "Name": "Guma Centre",
            "Address":
                "P 32, 2nd Avenue Federal Housing Estate, N/Bank, Makurdi"
          },
          {
            "Oid": 3,
            "Name": "Logo Centre",
            "Address": "Terhemen Akema Storage Facility, Ugba, Logo LGA"
          },
          {
            "Oid": 5,
            "Name": "Oturkpo Centre",
            "Address": "Grain Store, Lower Benue Okele Project, Otukpo"
          },
          {
            "Oid": 6,
            "Name": "Gboko Centre",
            "Address":
                "K3 New Road, Opposite former coca cola plant. Solar Schools Street, 
    Gboko"
          },
          {
            "Oid": 7,
            "Name": "Gwer East Centre",
            "Address":
                "Ahua Shardye's Warehouse, Behind Sylkan Filling Station, Ikpayongo , 
  G/East LGA"
          },
          {
            "Oid": 8,
            "Name": "Kwande Centre",
            "Address": "KM 3, Adagi Road, Adikpo"
          },
          {
            "Oid": 9,
            "Name": "Ohimini Centre",
            "Address": "Ajoga Oglewu, Ohimini"
          },
          {
            "Oid": 10,
            "Name": "Oju Centre",
            "Address": "Behind Town Hall, Ohuhu owo, Oju LGA"
          }
        ],
        "NoOfDistributionCentres": 8
      }
    ],
  };
  final _anchors = <Anchor>[];

  @override
  Widget build(BuildContext context) {
    // now you can use the anchors list here
    return Scaffold(
      body: ListView.builder(
        itemCount: _anchors.length,
        itemBuilder: (context, index) {
          final anchor = _anchors[index];
          return ListTile(
            title: Text(anchor.name),
            subtitle: Text(anchor.acronym),
            trailing: Text(anchor.distributionCenters?.length?.toString()),
            onTap: () {
              Navigator.push(
                context,
                MaterialPageRoute(
                  builder: (context) => AnchorPage(anchor: anchor),
                ),
              );
            },
          );
        },
      ),
    );
  }

  @override
  void initState() {
    super.initState();
    final anchors = _parseAnchors(anchorsMap);
    _anchors.addAll(anchors);
  }
}



回答2:


IF you want all addresses inside DistributionCentres

Column(
       children: <Widget>[
            Text(value[1]['Name']),
            Text(value[1]['Oid'].toString()),
            ListView.builder(
            itemCount:value[1]['DistributionCentres'].length
            context:context,
            builder:(BuilderContext context, int i){
             return Text(value[1]['DistributionCentres'][i]['Address'])
            }))
          ],
        ),

IF you want one address

Text(value[1]['DistributionCentres'][1]['Address'])

Like to remind for the value[1] you can pass the selected id from previous screen and used it here as value[selected id],

Hope this helps..




回答3:


Here is the Sketch that describes what I want to achieve Below. When Users click on an anchor it takes you to that single anchor details page where you will see all the distribution centers belonging to and anchor from there you can now add a record add the record that pertains to a center.



来源:https://stackoverflow.com/questions/62559731/how-can-i-iterate-over-an-array-of-objects-which-belong-to-a-key-value-flutter

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!