【问题标题】:Flutter: complex json serialization. Parsing json string to provide into UIFlutter:复杂的 json 序列化。解析 json 字符串以提供给 UI
【发布时间】:2020-10-07 05:56:36
【问题描述】:

这是我通过http请求得到的json字符串。 目的是根据当前工作日显示主题。

{
    "first_name": "First Name",
    "batch_name": "Batch 1",
    "enrolled_subjects": [
        "Subject 4",
        "Subject 5"
    ],
    "batch_timetable": {
        "Mon": {
            "Subject 4": [
                "6:00 PM - 7:00 PM"
            ],
            "Subject 5": [
                "5:00 PM - 6:00 PM",
                "7:00 PM - 8:00 PM"
            ],
            "Subject 6": [
                "8:00 PM - 9:00 PM"
            ]
        },
        "Tue": {
            "Subject 4": [
                "6:00 PM - 7:00 PM"
            ],
            "Subject 5": [
                "7:00 PM - 8:00 PM"
            ],
            "Subject 6": [
                "8:00 PM - 9:00 PM"
            ]
        }, ...so on upto "Sun"
    }
}

如何为这个json字符串设置模型类?

我尝试了这个模型类,但它给出了这个错误:type '_InternalLinkedHashMap<dynamic, dynamic>' is not a subtype of type 'Map<String, List<dynamic>>'

我也尝试过通过 quicktype 的 Model Class,但我认为这在这种情况下行不通。

class HomePageModel {
  HomePageModel({
    this.firstName,
    this.batchName,
    this.subjects,
    this.timetable,
  });

  String firstName;
  String batchName;
  List<String> subjects;
  Map timetable;

  factory HomePageModel.fromJson(Map<String, dynamic> json) => HomePageModel(
        firstName: json["first_name"],
        batchName: json["batch_name"],
        subjects: List<String>.from(json["subjects"].map((x) => x)),
        timetable: Map.from(json["timetable"])
            .map((key, value) => MapEntry(key, value)),
      );

  Map<String, dynamic> toJson() => {
        "first_name": firstName,
        "batch_name": batchName,
        "subjects": List<dynamic>.from(subjects.map((x) => x)),
        "timetable":
            Map.from(timetable.map((key, value) => MapEntry(key, value))),
      };
}

我正在使用 FutureBuilder 将这些数据显示到 UI 中。 任何帮助将不胜感激。

【问题讨论】:

    标签: json flutter dart json-serialization


    【解决方案1】:

    到目前为止,我已经为您创建了列表视图格式的 json 和示例,请查看它。

    以下是您提供的 json:

    {
        "first_name": "First Name",
        "batch_name": "Batch 1",
        "enrolled_subjects": [
            "Subject 4",
            "Subject 5"
        ],
        "batch_timetable": {
            "Mon": {
                "Subject 4": [
                    "6:00 PM - 7:00 PM"
                ],
                "Subject 5": [
                    "5:00 PM - 6:00 PM",
                    "7:00 PM - 8:00 PM"
                ],
                "Subject 6": [
                    "8:00 PM - 9:00 PM"
                ]
            },
            "Tue": {
                "Subject 4": [
                    "6:00 PM - 7:00 PM"
                ],
                "Subject 5": [
                    "7:00 PM - 8:00 PM"
                ],
                "Subject 6": [
                    "8:00 PM - 9:00 PM"
                ]
            }
        }
    }
    

    基于json我创建了一个ui

    import 'dart:convert';
    
    import 'package:flutter/material.dart';
    import 'package:flutter/services.dart';
    
    void main() => runApp(MyApp());
    
    class MyApp extends StatefulWidget {
      @override
      _MyAppState createState() => _MyAppState();
    }
    
    class _MyAppState extends State<MyApp> {
      bool _isLoading = false;
      List<Timings> timingsList = List();
    
      Future<String> loadFromAssets() async {
        return await rootBundle.loadString('json/parse.json');
      }
    
      @override
      void initState() {
        super.initState();
        dataLoadFunction();
      }
    
      dataLoadFunction() async {
        setState(() {
          _isLoading = true;
        });
        String jsonString = await loadFromAssets();
        Map newStringMap = json.decode(jsonString);
        //print(newStringMap['batch_timetable']);
    
        newStringMap['batch_timetable'].forEach((key, value) {
          List<Subjects> subjectsList = List();
    
          print(key);
    
          // print(value);
          value.forEach((key, value) {
            print(key);
            print(value);
            List<dynamic> timingValue = List();
            timingValue.add(value);
            Subjects subjects = Subjects(subjectName: key, timings: timingValue);
            subjectsList.add(subjects);
          });
    
          Timings sampleObject = Timings(
            day: key,
            subjectList: subjectsList,
          );
          timingsList.add(sampleObject);
        });
        print(timingsList.length);
    
    
        setState(() {
          _isLoading = false;
        });
      }
    
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          home: Scaffold(
            body: _isLoading
                ? CircularProgressIndicator()
                : ListView.builder(
                    itemCount: timingsList.length,
                    shrinkWrap: true,
                    itemBuilder: (BuildContext context, int index) {
                      return Card(
                        child: Column(
                          children: <Widget>[
                            Padding(
                              padding: const EdgeInsets.only(top:10,left:15),
                              child: Row(
                                children: <Widget>[
                                  Text('Day :'),
                                  Text(timingsList[index].day),
                                ],
                              ),
                            ),
                            Divider(color: Colors.grey,),
                            Column(
                              crossAxisAlignment: CrossAxisAlignment.start,
                              children: <Widget>[
                                Text(' Day wise Subjects are :'),
                                ListView.builder(
                                  itemCount: timingsList[index].subjectList.length,
                                  shrinkWrap: true,
                                  itemBuilder: (BuildContext context, int i) {
                                    return Column(
                                      crossAxisAlignment: CrossAxisAlignment.start,
                                      children: <Widget>[
                                        Text(timingsList[index]
                                            .subjectList[i]
                                            .subjectName),
                                        for (int j = 0;
                                            j <
                                                timingsList[index]
                                                    .subjectList[i]
                                                    .timings
                                                    .length;
                                            j++)
                                          Text(timingsList[index]
                                              .subjectList[i]
                                              .timings[j]
                                              .toString()),
                                      ],
                                    );
                                  },
                                )
                              ],
                            )
                          ],
                        ),
                      );
                    },
                  ),
          ),
        );
      }
    }
    
    class Timings {
      final String day;
      final List<Subjects> subjectList;
    
      Timings({
        this.day,
        this.subjectList,
      });
    }
    
    class Subjects {
      final String subjectName;
      final List<dynamic> timings;
    
      Subjects({this.subjectName, this.timings});
    }
    
    

    我刚刚添加了数据,你可以根据你想要的ui来装饰它:

    我在这段代码中实现了什么

    1) 数据将被动态获取,因此即使 json 发生变化,它也会相应地适应。

    2) 以列表视图格式添加,你可以做你想做的。

    提供了我制作的示例 ui

    让我知道它是否有效。

    【讨论】:

    • 谢谢,您的模型类结构消除了我的疑虑,我能够在我的 UI 中实现它。
    • 很高兴它对您有用,只需投上一票,以便对其他人有所帮助。
    【解决方案2】:

    使用这个:

    class HomePageModel {
      String firstName;
      String batchName;
      List<String> enrolledSubjects;
      BatchTimetable batchTimetable;
    
      HomePageModel(
          {this.firstName,
          this.batchName,
          this.enrolledSubjects,
          this.batchTimetable});
    
      HomePageModel.fromJson(Map<String, dynamic> json) {
        firstName = json['first_name'];
        batchName = json['batch_name'];
        enrolledSubjects = json['enrolled_subjects'].cast<String>();
        batchTimetable = json['batch_timetable'] != null
            ? new BatchTimetable.fromJson(json['batch_timetable'])
            : null;
      }
    
      Map<String, dynamic> toJson() {
        final Map<String, dynamic> data = new Map<String, dynamic>();
        data['first_name'] = this.firstName;
        data['batch_name'] = this.batchName;
        data['enrolled_subjects'] = this.enrolledSubjects;
        if (this.batchTimetable != null) {
          data['batch_timetable'] = this.batchTimetable.toJson();
        }
        return data;
      }
    }
    
    class BatchTimetable {
      Mon mon;
      Mon tue;
    
      BatchTimetable({this.mon, this.tue});
    
      BatchTimetable.fromJson(Map<String, dynamic> json) {
        mon = json['Mon'] != null ? new Mon.fromJson(json['Mon']) : null;
        tue = json['Tue'] != null ? new Mon.fromJson(json['Tue']) : null;
      }
    
      Map<String, dynamic> toJson() {
        final Map<String, dynamic> data = new Map<String, dynamic>();
        if (this.mon != null) {
          data['Mon'] = this.mon.toJson();
        }
        if (this.tue != null) {
          data['Tue'] = this.tue.toJson();
        }
        return data;
      }
    }
    
    class Mon {
      List<String> subject4;
      List<String> subject5;
      List<String> subject6;
    
      Mon({this.subject4, this.subject5, this.subject6});
    
      Mon.fromJson(Map<String, dynamic> json) {
        subject4 = json['Subject 4'].cast<String>();
        subject5 = json['Subject 5'].cast<String>();
        subject6 = json['Subject 6'].cast<String>();
      }
    
      Map<String, dynamic> toJson() {
        final Map<String, dynamic> data = new Map<String, dynamic>();
        data['Subject 4'] = this.subject4;
        data['Subject 5'] = this.subject5;
        data['Subject 6'] = this.subject6;
        return data;
      }
    }

    【讨论】:

    • 我怎样才能从这个模型中得到根据工作日的时间表?
    • 这个类是你的json标准,你可以使用calandar插件来实现你的目标。
    • 我想要像 timetable['Mon'] 这样的东西,其中包含“星期一”的数据。
    【解决方案3】:

    休息法:

    import 'package:http/http.dart' as http;
    
    Future<HomePageModel> restSample() async {
      var response = await http.get('your URL');
      var jsonResponse = json.decode(response.body);
      HomePageModel homePageModel = HomePageModel.fromJson(jsonResponse);
      return homePageModel;
    }
    

    调用时间表参数:

    homePageModel.batchTimetable.mon;
    

    【讨论】:

      猜你喜欢
      • 2020-10-29
      • 2021-06-20
      • 2013-01-06
      • 2020-04-13
      • 2014-04-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多