Flutter:复杂的 json 序列化。正在解析 json 字符串以提供给 UI
Flutter: complex json serialization. Parsing json string to provide into UI
这是我通过 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 字符串设置模型 Class?
我试过这个模型 Class 但它给出了这个错误:type '_InternalLinkedHashMap<dynamic, dynamic>' is not a subtype of type 'Map<String, List<dynamic>>'
我也试过使用 quicktype 的模型 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。
任何帮助将不胜感激。
使用这个:
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;
}
}
休息方法:
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;
与您提供的 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
让我知道它是否有效。
这是我通过 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 字符串设置模型 Class?
我试过这个模型 Class 但它给出了这个错误:type '_InternalLinkedHashMap<dynamic, dynamic>' is not a subtype of type 'Map<String, List<dynamic>>'
我也试过使用 quicktype 的模型 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。 任何帮助将不胜感激。
使用这个:
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;
}
}
休息方法:
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;
与您提供的 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
让我知道它是否有效。