5

I have a JSON file like that:

[
  {
    "id": 1,
    "continent": "North America",
    "country": [
      {
        "name": "United States",
        "capital": "Washington, D.C.",
        "language": [
          "English"
        ]
      },
      {
        "name": "Canada",
        "capital": "Ottawa",
        "language": [
          "English",
          "French"
        ]
      }
    ]
  },
  {
    "id": 2,
    "continent": "Europe",
    "country": [
      {
        "name": "Germany",
        "capital": "Berlin",
        "language": [
          "German"
        ]
      }
    ]
  }
]

I used https://app.quicktype.io/ to parse JSON data. I have created a ListView.builder to display the names of continents. Now I want to show "country name", "capital", and "language" for each continent.

enter image description here

So please help me do that, this is the main file

import 'package:flutter/material.dart';
import 'model/continent_model.dart';
import 'services/continent_services.dart';

class ContinentPage extends StatefulWidget {
  ContinentPage() : super();
  @override
  _ContinentPageState createState() => _ContinentPageState();
}

class _ContinentPageState extends State<ContinentPage> {
  List<Continent> _continent;
  List<Country> _country;

  @override
  void initState() {
    super.initState();
    ContinentServices.getContinent().then((continents) {
      setState(() {
        _continent = continents;
      });
    });
  }

  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(),
        body: Container(
            child: ListView.builder(
                itemCount: null == _continent ? 0 : _continent.length,
                itemBuilder: (context, index) {
                  return Row(
                    mainAxisAlignment: MainAxisAlignment.spaceBetween,
                    children: <Widget>[
                      Text(_continent[index].continent),
                      // how to create a ListView show a Column that includes:
                      // _country[index].name,
                      // _country[index].capital,
                      // _country[index].language,
                    ],
                  );
                })));
  }
}

2 Answers 2

2

You can copy paste run full code below
You can use nested ListView.separated
code snippet

ListView.separated(
            separatorBuilder: (BuildContext context, int index) {
              return SizedBox(
                height: 10,
              );
            },
            shrinkWrap: true,
            itemCount: null == _continent ? 0 : _continent.length,
            itemBuilder: (context, index) {
              return Column(
                mainAxisAlignment: MainAxisAlignment.center,
                crossAxisAlignment: CrossAxisAlignment.center,
                children: <Widget>[
                  Row(
                      mainAxisAlignment: MainAxisAlignment.center,
                      crossAxisAlignment: CrossAxisAlignment.center,
                      children: <Widget>[
                        Expanded(
                            flex: 1, child: Text(_continent[index].continent)),
                        Expanded(
                          flex: 2,
                          child: Container(
                            height: 50,
                            child: ListView.separated(
                                separatorBuilder:

It's too long to describe all the detail, you can directly reference full code

working demo

enter image description here

full code

import 'package:flutter/material.dart';
// To parse this JSON data, do
//
//     final continent = continentFromJson(jsonString);

import 'dart:convert';

List<Continent> continentFromJson(String str) =>
    List<Continent>.from(json.decode(str).map((x) => Continent.fromJson(x)));

String continentToJson(List<Continent> data) =>
    json.encode(List<dynamic>.from(data.map((x) => x.toJson())));

class Continent {
  Continent({
    this.id,
    this.continent,
    this.country,
  });

  int id;
  String continent;
  List<Country> country;

  factory Continent.fromJson(Map<String, dynamic> json) => Continent(
        id: json["id"],
        continent: json["continent"],
        country:
            List<Country>.from(json["country"].map((x) => Country.fromJson(x))),
      );

  Map<String, dynamic> toJson() => {
        "id": id,
        "continent": continent,
        "country": List<dynamic>.from(country.map((x) => x.toJson())),
      };
}

class Country {
  Country({
    this.name,
    this.capital,
    this.language,
  });

  String name;
  String capital;
  List<String> language;

  factory Country.fromJson(Map<String, dynamic> json) => Country(
        name: json["name"],
        capital: json["capital"],
        language: List<String>.from(json["language"].map((x) => x)),
      );

  Map<String, dynamic> toJson() => {
        "name": name,
        "capital": capital,
        "language": List<dynamic>.from(language.map((x) => x)),
      };
}

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),
      home: MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class ContinentServices {
  Future<List<Continent>> getContinent() {
    String jsonString = '''
    [
  {
    "id": 1,
    "continent": "North America",
    "country": [
      {
        "name": "United States",
        "capital": "Washington, D.C.",
        "language": [
          "English"
        ]
      },
      {
        "name": "Canada",
        "capital": "Ottawa",
        "language": [
          "English",
          "French"
        ]
      }
    ]
  },
  {
    "id": 2,
    "continent": "Europe",
    "country": [
      {
        "name": "Germany",
        "capital": "Berlin",
        "language": [
          "German"
        ]
      }
    ]
  }
]
    ''';
    List<Continent> continentList = continentFromJson(jsonString);
    return Future.value(continentList);
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

  final String title;

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

class _MyHomePageState extends State<MyHomePage> {
  List<Continent> _continent;

  @override
  void initState() {
    super.initState();
    ContinentServices().getContinent().then((continents) {
      setState(() {
        _continent = continents;
      });
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: Text(widget.title),
        ),
        body: ListView.separated(
            separatorBuilder: (BuildContext context, int index) {
              return SizedBox(
                height: 10,
              );
            },
            shrinkWrap: true,
            itemCount: null == _continent ? 0 : _continent.length,
            itemBuilder: (context, index) {
              return Column(
                mainAxisAlignment: MainAxisAlignment.center,
                crossAxisAlignment: CrossAxisAlignment.center,
                children: <Widget>[
                  Row(
                      mainAxisAlignment: MainAxisAlignment.center,
                      crossAxisAlignment: CrossAxisAlignment.center,
                      children: <Widget>[
                        Expanded(
                            flex: 1, child: Text(_continent[index].continent)),
                        Expanded(
                          flex: 2,
                          child: Container(
                            height: 50,
                            child: ListView.separated(
                                separatorBuilder:
                                    (BuildContext context, int index) {
                                  return SizedBox(
                                    width: 10,
                                  );
                                },
                                shrinkWrap: true,
                                scrollDirection: Axis.horizontal,
                                itemCount: null == _continent
                                    ? 0
                                    : _continent[index].country.length,
                                itemBuilder: (context, countryIndex) {
                                  print(_continent[index]
                                      .country[countryIndex]
                                      .name);
                                  return Row(
                                      mainAxisAlignment:
                                          MainAxisAlignment.center,
                                      crossAxisAlignment:
                                          CrossAxisAlignment.center,
                                      children: <Widget>[
                                        Container(
                                          width: 120,
                                          child: Column(
                                            children: <Widget>[
                                              Text(
                                                _continent[index]
                                                    .country[countryIndex]
                                                    .name,
                                                style: TextStyle(
                                                    color: Colors.red),
                                              ),
                                              Text(
                                                  _continent[index]
                                                      .country[countryIndex]
                                                      .capital,
                                                  style: TextStyle(
                                                      color: Colors.red)),
                                              Expanded(
                                                child: ListView.separated(
                                                    separatorBuilder:
                                                        (BuildContext context,
                                                            int index) {
                                                      return SizedBox(
                                                        width: 2,
                                                      );
                                                    },
                                                    shrinkWrap: true,
                                                    scrollDirection:
                                                        Axis.horizontal,
                                                    itemCount: null ==
                                                            _continent
                                                        ? 0
                                                        : _continent[index]
                                                            .country[
                                                                countryIndex]
                                                            .language
                                                            .length,
                                                    itemBuilder: (context,
                                                        languageIndex) {
                                                      return Row(
                                                          mainAxisAlignment:
                                                              MainAxisAlignment
                                                                  .spaceEvenly,
                                                          children: <Widget>[
                                                            Text(
                                                                _continent[index]
                                                                        .country[
                                                                            countryIndex]
                                                                        .language[
                                                                    languageIndex],
                                                                style: TextStyle(
                                                                    color: Colors
                                                                        .red)),
                                                          ]);
                                                    }),
                                              ),
                                            ],
                                          ),
                                        )
                                      ]);
                                }),
                          ),
                        )
                      ])
                ],
              );
            }));
  }
}
Sign up to request clarification or add additional context in comments.

5 Comments

I still have to say thank you very much for your thoughtfulness in helping me. Your code is incredible, I have learned a lot from it xD
Can I have one more favor? I want the 2nd ListView.separated:=> itemCount: 3, its width will fit the left screen, cannot be scrolled horizontal and split evenly for 3 columns (like Expanded flex 1: 1: 1) image, the Text in that will automatically resize to fit, I think AutoSizeText is great. So is there any way to do that?
I would suggest post your request to a new question to allow more people can help you. Responsive for different screen size is a huge topic.
I see, will do it. Thanks :D
I posted new question here xD
2

You need to place the second listview.builder inside a container with a defined height.

Container(
  height: 120,
  child: ListView.builder(
    shrinkWrap: true,
    scrollDirection: Axis.horizontal,
    itemCount: map.length,
    itemBuilder: (context, index) => Column(
      children: [
        Text(_country.elementAt(index).name),
        Text(_country.elementAt(index).capital),
Text(_country.elementAt(index).language),
      ],
    ),
  ),
)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.