【问题标题】:Can't decode/Parse Json type list<String> with this list<String> type Model in Dart无法在 Dart 中使用此列表<String> 类型模型解码/解析 Json 类型列表<String>
【发布时间】:2021-01-11 05:48:41
【问题描述】:

我想从 json 列表中创建一个下拉列表。我正在使用app.quicktype.io 将 json 转换为 PODO(普通旧 dart 对象)

这是我的 JSON 数据:

[
  {
    "country_name": "Andorra",
    "alpha2_code": "AD",
    "country_code": "376",
    "states": [
      { "state_name": "Andorra la Vella" },
      { "state_name": "Canillo" }
    ]
  },
  ]

这是我创建的 PODO(普通旧 Dart 对象) app.quicktype.io:

class CountryDetailsModel {
  CountryDetailsModel({
    this.countryName,
    this.alpha2Code,
    this.countryCode,
    this.states,
  });

  String countryName;
  String alpha2Code;
  String countryCode;
  List<StateNames> states;

  factory CountryDetailsModel.fromJson(Map<String, dynamic> json) =>
      CountryDetailsModel(
        countryName: json["country_name"],
        alpha2Code: json["alpha2_code"],
        countryCode: json["country_code"],
        states: List<StateNames>.from(
            json["states"].map((x) => StateNames.fromJson(x))),
      );

  Map<String, dynamic> toJson() => {
        "country_name": countryName,
        "alpha2_code": alpha2Code,
        "country_code": countryCode,
        "states": List<dynamic>.from(states.map((x) => x.toJson())),
      };
}

class StateNames {
  StateNames({
    this.stateName,
  });

  String stateName;

  factory StateNames.fromJson(Map<String, dynamic> json) => StateNames(
        stateName: json["state_name"],
      );

  Map<String, dynamic> toJson() => {
        "state_name": stateName,
      };
}

【问题讨论】:

    标签: json flutter dart


    【解决方案1】:

    您可以在下面复制粘贴运行完整代码
    在工作演示中,用 3 秒模拟网络延迟
    您可以使用FutureBuilderreturn countryDetailsModelFromJson(jsonString);
    代码sn-p

    Future<List<CountryDetailsModel>> getHttp() async {
        String jsonString = ...
    
        return countryDetailsModelFromJson(jsonString);
    }
    ...  
    FutureBuilder(
                future: _future,
                builder:
                    (context, AsyncSnapshot<List<CountryDetailsModel>> snapshot) {
                  ...
                        return DropdownButton<CountryDetailsModel>(
                          //isDense: true,
                          hint: Text('Choose'),
                          value: _selectedValue,
                          icon: Icon(Icons.check_circle_outline),
                          iconSize: 24,
                          elevation: 16,
                          style: TextStyle(color: Colors.deepPurple),
                          underline: Container(
                            height: 2,
                            color: Colors.blue[300],
                          ),
                          onChanged: (CountryDetailsModel newValue) {
                            setState(() {
                              _selectedValue = newValue;
                            });
                          },
                          items: snapshot.data
                              .map<DropdownMenuItem<CountryDetailsModel>>(
                                  (CountryDetailsModel value) {
                            return DropdownMenuItem<CountryDetailsModel>(
                              value: value,
                              child: Text(value.countryName),
                            );
                          }).toList(),
                        );
                      }
                  }
                })
    

    工作演示

    完整代码

    import 'package:flutter/material.dart';
    import 'package:http/http.dart' as http;
    import 'dart:convert';
    
    List<CountryDetailsModel> countryDetailsModelFromJson(String str) =>
        List<CountryDetailsModel>.from(
            json.decode(str).map((x) => CountryDetailsModel.fromJson(x)));
    
    String countryDetailsModelToJson(List<CountryDetailsModel> data) =>
        json.encode(List<dynamic>.from(data.map((x) => x.toJson())));
    
    class CountryDetailsModel {
      CountryDetailsModel({
        this.countryName,
        this.alpha2Code,
        this.countryCode,
        this.states,
      });
    
      String countryName;
      String alpha2Code;
      String countryCode;
      List<StateNames> states;
    
      factory CountryDetailsModel.fromJson(Map<String, dynamic> json) =>
          CountryDetailsModel(
            countryName: json["country_name"],
            alpha2Code: json["alpha2_code"],
            countryCode: json["country_code"],
            states: List<StateNames>.from(
                json["states"].map((x) => StateNames.fromJson(x))),
          );
    
      Map<String, dynamic> toJson() => {
            "country_name": countryName,
            "alpha2_code": alpha2Code,
            "country_code": countryCode,
            "states": List<dynamic>.from(states.map((x) => x.toJson())),
          };
    }
    
    class StateNames {
      StateNames({
        this.stateName,
      });
    
      String stateName;
    
      factory StateNames.fromJson(Map<String, dynamic> json) => StateNames(
            stateName: json["state_name"],
          );
    
      Map<String, dynamic> toJson() => {
            "state_name": stateName,
          };
    }
    
    void main() => runApp(MyApp());
    
    /// This Widget is the main application widget.
    class MyApp extends StatelessWidget {
      static const String _title = 'Flutter Code Sample';
    
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          title: _title,
          home: Scaffold(
            appBar: AppBar(title: const Text(_title)),
            body: MyStatefulWidget(),
          ),
        );
      }
    }
    
    class MyStatefulWidget extends StatefulWidget {
      MyStatefulWidget({Key key}) : super(key: key);
    
      @override
      _MyStatefulWidgetState createState() => _MyStatefulWidgetState();
    }
    
    class _MyStatefulWidgetState extends State<MyStatefulWidget> {
      CountryDetailsModel _selectedValue;
      Future<List<CountryDetailsModel>> _future;
    
      Future<List<CountryDetailsModel>> getHttp() async {
        String jsonString = '''
        [
      {
        "country_name": "Andorra",
        "alpha2_code": "AD",
        "country_code": "376",
        "states": [
          { "state_name": "Andorra la Vella" },
          { "state_name": "Canillo" },
          { "state_name": "Encamp" },
          { "state_name": "La Massana" },
          { "state_name": "Les Escaldes" },
          { "state_name": "Ordino" },
          { "state_name": "Sant Julia de Loria" }
        ]
      },
      {
        "country_name": "Azerbaijan",
        "alpha2_code": "AZ",
        "country_code": "994",
        "states": [
          { "state_name": "Abseron" },
          { "state_name": "Baki Sahari" },
          { "state_name": "Ganca" },
          { "state_name": "Ganja" },
          { "state_name": "Kalbacar" },
          { "state_name": "Lankaran" },
          { "state_name": "Mil-Qarabax" },
          { "state_name": "Mugan-Salyan" },
          { "state_name": "Nagorni-Qarabax" },
          { "state_name": "Naxcivan" },
          { "state_name": "Priaraks" },
          { "state_name": "Qazax" },
          { "state_name": "Saki" },
          { "state_name": "Sirvan" },
          { "state_name": "Xacmaz" }
        ]
      }]
        ''';
    
        return countryDetailsModelFromJson(jsonString);
    
      }
    
      @override
      void initState() {
        _future = getHttp();
        super.initState();
      }
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
            body: FutureBuilder(
                future: _future,
                builder:
                    (context, AsyncSnapshot<List<CountryDetailsModel>> snapshot) {
                  switch (snapshot.connectionState) {
                    case ConnectionState.none:
                      return Text('none');
                    case ConnectionState.waiting:
                      return Center(child: CircularProgressIndicator());
                    case ConnectionState.active:
                      return Text('');
                    case ConnectionState.done:
                      if (snapshot.hasError) {
                        return Text(
                          '${snapshot.error}',
                          style: TextStyle(color: Colors.red),
                        );
                      } else {
                        return DropdownButton<CountryDetailsModel>(
                          //isDense: true,
                          hint: Text('Choose'),
                          value: _selectedValue,
                          icon: Icon(Icons.check_circle_outline),
                          iconSize: 24,
                          elevation: 16,
                          style: TextStyle(color: Colors.deepPurple),
                          underline: Container(
                            height: 2,
                            color: Colors.blue[300],
                          ),
                          onChanged: (CountryDetailsModel newValue) {
                            setState(() {
                              _selectedValue = newValue;
                            });
                          },
                          items: snapshot.data
                              .map<DropdownMenuItem<CountryDetailsModel>>(
                                  (CountryDetailsModel value) {
                            return DropdownMenuItem<CountryDetailsModel>(
                              value: value,
                              child: Text(value.countryName),
                            );
                          }).toList(),
                        );
                      }
                  }
                }));
      }
    }
    

    【讨论】:

    • 有什么办法不等3秒?我不想等待特定的 3 秒。有什么方法可以通过 await 等待动态时间?
    • 我没有你的api,它只是模拟的,所以你可以看到CircularProgressIndicator(),你可以直接去掉那行。
    • 您可以直接删除 Future.delayed 并替换为您的 api 调用,例如 http.Response response = http.get 或 post
    • 这个国家数据不是来自api。这是在我的应用程序飞镖文件中。我将所有字符串从 json 文件复制到我的应用程序模型 dart 文件中。这是json文件。我复制了这个 json 中的所有文本并将其粘贴到 ''' ''' this 中的类变量中。这是 json 链接:github.com/santoshakil-office/get_country_details/blob/master/…
    • 你可以做 return countryDetailsModelFromJson(jsonString);直接地。我已经测试过了。你可以看到更新的工作演示
    【解决方案2】:

    终于找到了解决办法。

    流程如下:

    List<CountryDetailsModel> countryDetails() {
        List<Map> map = CountryData.countryData;
        List<CountryDetailsModel> list =
            map.map((json) => CountryDetailsModel.fromJson(json)).toList();
        return list;
      }
    

    对于打印所有国家/地区:

    countryDetails().
       forEach((element) {
             print(element.countryName);
    });
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-10-08
      • 1970-01-01
      • 1970-01-01
      • 2018-09-18
      • 2019-03-15
      • 2021-06-12
      • 2023-02-02
      • 1970-01-01
      相关资源
      最近更新 更多