Home > Blockchain >  Drawer list only shows one key item from json object
Drawer list only shows one key item from json object

Time:03-14

I am able to show the first object of the key menu with the key value Books but i cannot show the second object key value Authors inside the Drawer() widget. I grab the following json object:

{
  "data": {
    "user" : "user1",
    "menu": [
      {
        "label": "Books",
        "view": "books"
      },
      {
        "label": "Authors",
        "view": "authors"
      }


    ]
  }
}

I grab this json object with the following method:



class TestData {
  Future<Map<String, dynamic>> getTestData() async {
    String jsonData =
        await rootBundle.loadString('assets/test_json/test_json1.json');
    Map<String, dynamic> data = jsonDecode(jsonData);
    return data;
  }
}

And i also view a list of menu with the key label from the grabbed json object inside a Drawer() widget:



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

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

class _MenuState extends State<Menu> {
  late Map<String, dynamic> grabbedData = {};

  setTestData() async {
    await TestData()
        .getTestData()
        .then((result) => setState(() => grabbedData = result));
  }

  @override
  initState() {
    setTestData();
  }

  @override
  Widget build(BuildContext context) {
    Map<String, dynamic> data = grabbedData;
    return Drawer(
        child: ListView(padding: EdgeInsets.zero, children: [
      DrawerHeader(
          child: Center(
        child: Container(),
      )),
      Column(
        children: [
          ListView.builder(
              physics: const NeverScrollableScrollPhysics(),
              shrinkWrap: true,
              itemCount: data.keys.length,
              itemBuilder: (BuildContext context, int index) {
                return ListTile(
                  onTap: () {},
                  title: Center(
                    child: Column(
                      children: [
                        Text(
                          data["data"]["menu"][index]["label"],
                          style: TextStyle(fontSize: 20, color: Colors.white),
                        ),
                      ],
                    ),
                  ),
                );
              }),
        ],
      ),
    ]));
  }
}

But the problem is that the Drawer only shows the first object with the key value Books. I know it has to do with the itemCount: data.keys.length but i don't know the right way to show all the objects from the key menu.

CodePudding user response:

enter image description here

set your item count like this

 itemCount: grabbedData.containsKey("data")
              ? (grabbedData["data"]["menu"] as List<Map<String, dynamic>>)
                  .length
              : 0,

in your widget like this

Text(
                (grabbedData["data"]["menu"] as List<Map<String, dynamic>>)[index]["label"],
                style: TextStyle(fontSize: 20, color: Colors.black),
              )

SAmpleCode

import 'dart:async';

import 'package:flutter/cupertino.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:image_picker/image_picker.dart';

ImagePicker? picker;

void main() {
  WidgetsFlutterBinding.ensureInitialized();

  runApp(MyApp());
}

class TestData {
  Future<Map<String, dynamic>> getTestData() async {
    var jsonData = {
      "data": {
        "user": "user1",
        "menu": [
          {"label": "Books", "view": "books"},
          {"label": "Authors", "view": "authors"}
        ]
      }
    };
    // await rootBundle.loadString('assets/test_json/test_json1.json');
    // Map<String, dynamic> data = jsonDecode(jsonData);
    return jsonData;
  }
}

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'MySQL Test',
      theme: ThemeData(
        primarySwatch: Colors.blue,
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),
      home: Scaffold(drawer: Menu(), body: Container()),
    );
  }
}

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

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

class _MenuState extends State<Menu> {
  Map<String, dynamic> grabbedData = {
    "data": {
      "user": "user1",
      "menu": [
        {"label": "Books", "view": "books"},
        {"label": "Authors", "view": "authors"}
      ]
    }
  };

  setTestData() async {
    await TestData()
        .getTestData()
        .then((result) => setState(() => grabbedData = result));
  }

  @override
  initState() {
    setTestData();
  }

  @override
  Widget build(BuildContext context) {
    // Map<String, dynamic> data = grabbedData;
    // var data2 = data["data"]["menu"] as List<Map<String, dynamic>>;
    return Drawer(
        child: ListView(padding: EdgeInsets.zero, children: [
      DrawerHeader(
          child: Center(
        child: Container(),
      )),
      ListView.builder(
          physics: const NeverScrollableScrollPhysics(),
          shrinkWrap: true,
          itemCount:  (grabbedData["data"]["menu"] as List<Map<String, dynamic>>).length,
          itemBuilder: (BuildContext context, int index) {
            // print(index);
            // print((grabbedData["data"]["menu"] as List<Map<String, dynamic>>).length);

            return ListTile(
              onTap: () {},
              title: Text(
                (grabbedData["data"]["menu"] as List<Map<String, dynamic>>)[index]["label"],
                style: TextStyle(fontSize: 20, color: Colors.black),
              ),
            );
          }),
    ]));
  }
}
  • Related