我将使用真实的json。首先,我应该运行用Flask编写的项目,然后使用本地主机来获取数据。 这是我正在使用的真正的Json
{“ devices”:[{“ device_desc”:“ cooler”,“ device_title”:“ cooler”,“ functions :: [{” device_id“:1,” function_desc“:” pomp“,” function_title“: “ pomp”,“ status”:1},{“ device_id”:1,“ function_desc”:“ less”,“ function_title”:“ less”,“ status”:1},{“ device_id”:1,“ function_desc “:” up“,” function_title“:” up“,” status“:1}],” image_path“:” fdfdfsf“,” status_id“:1,” statuss“:{” status_desc“:”设备已开启“ ,“ status_title”:“ on”}},{“ device_desc”:“ panke”,“ device_title”:“ panke”,“ functions”:[{“ device_id”:2,“ function_desc”:“ less”,“ function_title “:” pomp“,”状态“:2},{” device_id“:2,” function_desc“:”少“,” function_title“:”少“,”状态“:2}],” image_path“:” vfx “,” status_id“:2,” statuss“:{” status_desc“:”设备已关闭“,” status_title“:”关闭“}}}}
为了更好地理解,我在下面提供了屏幕截图
,这是解析json的站点的链接: http://json.parser.online.fr/
最后,这是我的代码:
这些是用于定义json属性的数据模型:
class Base{
//the type of our object is the array
List<Device> _devices;
Base(this._devices);
List<Device> get devices => _devices;
set devices(List<Device> value) {
_devices = value;
}
}
class Device {
String _device_desc,_device_title,_image_path;
int _status_id;
List<function> _functions;
List<Status> _statuss ;
Device(this._device_desc, this._device_title, this._image_path,
this._status_id, this._functions, this._statuss);
List<Status> get statuss => _statuss;
set statuss(List<Status> value) {
_statuss = value;
}
List<function> get functions => _functions;
set functions(List<function> value) {
_functions = value;
}
int get status_id => _status_id;
set status_id(int value) {
_status_id = value;
}
get image_path => _image_path;
set image_path(value) {
_image_path = value;
}
get device_title => _device_title;
set device_title(value) {
_device_title = value;
}
String get device_desc => _device_desc;
set device_desc(String value) {
_device_desc = value;
}
}
class Status {
String _status_desc, _status_title;
Status(this._status_desc, this._status_title);
get status_title => _status_title;
set status_title(value) {
_status_title = value;
}
String get status_desc => _status_desc;
set status_desc(String value) {
_status_desc = value;
}}
class function {
String _function_desc, _function_title;
int _device_id, _status;
function(this._function_desc, this._function_title, this._device_id,
this._status);
get status => _status;
set status(value) {
_status = value;
}
int get device_id => _device_id;
set device_id(int value) {
_device_id = value;
}
get function_title => _function_title;
set function_title(value) {
_function_title = value;
}
String get function_desc => _function_desc;
set function_desc(String value) {
_function_desc = value;
}}
这是有状态类:
class MyHomePage extends StatefulWidget {
var title;
MyHomePage({Key key, this.title}) : super(key: key);
@override
_MyHomePageState createState() => new _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
Future<Base> _getBase() async {
var data = await http.get(Uri.encodeFull("http://192.168.1.111:5000/mobile-home"));
var jsonData = json.decode(data.body);
Base base = Base(jsonData);
return Base(jsonData[0]);
}
@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text(widget.title),
),
body: Container(
child: FutureBuilder(
future: _getBase(),
builder: (BuildContext context, AsyncSnapshot snapshot) {
if (snapshot.data == null) {
return Container(
child: Center(
child: Text("Loading..."),
),
);
} else {
return ListView.builder(
itemCount: snapshot.data.devices.length,
itemBuilder: (BuildContext context, int index) {
snapshot.data.devices.map<Widget>((devices){
return ListTile(
subtitle: Text(devices[index].device_desc.toString()),
title: Text(devices[index].device_title),
/*leading: CircleAvatar(
// ignore: argument_type_not_assignable
backgroundImage: NetworkImage(snapshot.data[index].thumbnailUrl),
)*/
);
}
);
},
);
}
},
),
),
);
}
}
调试时出现错误,即 “类型“列表”不是类型“列表”的子类型”
因此,我无法从json获取数据 tnx寻求帮助:)
答案 0 :(得分:2)
关于如何在Flutter中解析复杂的JSON有一个很好的article。快速摘要...
简单的东西:
{
"id":"487349",
"name":"Pooja Bhaumik",
"score" : 1000
}
成为...
class Student{
String studentId;
String studentName;
int studentScores;
Student({
this.studentId,
this.studentName,
this.studentScores
});
factory Student.fromJson(Map<String, dynamic> parsedJson){
return Student(
studentId: parsedJson['id'],
studentName : parsedJson['name'],
studentScores : parsedJson ['score']
);
}
}
您创建一个新的Student对象,例如Student.fromJson(your_parsed_json)
。
子对象以类似的方式工作。对于父对象内的每个对象,您将创建一个新的Dart对象,每个对象都具有自己的fromJson解析器。然后,在父工厂内部,您可以从fromJson方法中调用它(像这样)...这也适用于对象列表。
factory Student.fromJson(Map<String, dynamic> parsedJson){
return Student(
studentId: parsedJson['id'],
studentName : parsedJson['name'],
studentScores : Teacher.fromJson(parsedJson['teacher'])
);
答案 1 :(得分:2)
您的问题中没有问题,但我认为问题是:
我的Json代码不起作用-如何有效解析和编码我的复杂json对象 颤振程序。
对于复杂的JSON,您可能需要考虑使用代码生成来减少必须编写的样板。扑动页面使用JsonSerializable是一个很好的例子。这里是您示例的基本说明:
pubspec.yaml
并在命令行中运行flutter pub get
:dependencies: json_annotation: ^1.2.0 dev_dependencies: build_runner: ^1.0.0 json_serializable: ^1.5.1
创建基本的对象模型(类似于您所做的事情)。除了以下差异:
要启用json样板代码生成,请执行以下三个步骤:
@JsonSerializable() class Base { List<Device> devices; Base({this.devices}); factory Base.fromJson(Map<String, dynamic> json) => _$BaseFromJson(json); Map<String, dynamic> toJson() => _$BaseToJson(this); } @JsonSerializable() class Device { String device_desc,device_title,image_path; int status_id; List<function> functions; Status statuss ; Device(this.device_desc, this.device_title, this.image_path, this.status_id, this.functions, this.statuss); factory Device.fromJson(Map<String, dynamic> json) => _$DeviceFromJson(json); Map<String, dynamic> toJson() => _$DeviceToJson(this); } @JsonSerializable() class Status { String status_desc, status_title; Status(this.status_desc, this.status_title); factory Status.fromJson(Map<String, dynamic> json) => _$StatusFromJson(json); Map<String, dynamic> toJson() => _$StatusToJson(this); } @JsonSerializable() class function { String function_desc, function_title; int device_id, status; function(this.function_desc, this.function_title, this.device_id, this.status); factory function.fromJson(Map<String, dynamic> json) => _$functionFromJson(json); Map<String, dynamic> toJson() => _$functionToJson(this); }
flutter packages pub run build_runner watch
part
关键字将此文件添加到您自己的源文件中,例如,如果您的源文件为main.dart
,则添加以下行:part 'main.g.dart';
您已经做好了-这就是测试编码/解码所需的全部。例如,使用以下代码:
import 'dart:convert';
void main() => (){
var jsonExample = '{"devices": [{"device_desc": "cooler", "device_title": "cooler", "functions": [{"device_id": 1, "function_desc": "pomp", "function_title": "pomp", "status": 1}, {"device_id": 1, "function_desc": "less", "function_title": "less", "status": 1}, {"device_id": 1, "function_desc": "up", "function_title": "up", "status": 1}], "image_path": "fdfdfsf", "status_id": 1, "statuss": {"status_desc": "device is on", "status_title": "on"}}, {"device_desc": "panke", "device_title": "panke", "functions": [{"device_id": 2, "function_desc": "less", "function_title": "pomp", "status": 2}, {"device_id": 2, "function_desc": "less", "function_title": "less", "status": 2}], "image_path": "vfx", "status_id": 2, "statuss": {"status_desc": "device is off", "status_title": "off"}}]}';
Map base_example = json.decode(jsonExample);
Base base_example_parsed = Base.fromJson(base_example);
var numberDevices = base_example_parsed.devices.length;
var numberFuncs = base_example_parsed.devices[0].functions.length;
print('$base_example_parsed has $numberDevices devices and the first device has $numberFuncs functions');
var base_example_encoded_again = json.encode(base_example_parsed);
print('$base_example_encoded_again');
};
有关更多信息,请参阅: 1. official example。 2.这个blog。
答案 2 :(得分:0)
调试时出现错误,即“列表类型不是列表类型的子类型”
此示例应该可以正常工作。
import 'dart:convert';
import 'json_objects.dart';
void main() {
var jsonObject = jsonDecode(_data) as Map<String, dynamic>;
var response = Response1.fromJson(jsonObject);
for (var device in response.devices) {
print(device.deviceTitle);
for (var function in device.functions) {
print(' ' + function.functionTitle);
}
}
}
var _data = '''
{"devices": [{"device_desc": "cooler", "device_title": "cooler", "functions": [{"device_id": 1, "function_desc": "pomp", "function_title": "pomp", "status": 1}, {"device_id": 1, "function_desc": "less", "function_title": "less", "status": 1}, {"device_id": 1, "function_desc": "up", "function_title": "up", "status": 1}], "image_path": "fdfdfsf", "status_id": 1, "statuss": {"status_desc": "device is on", "status_title": "on"}}, {"device_desc": "panke", "device_title": "panke", "functions": [{"device_id": 2, "function_desc": "less", "function_title": "pomp", "status": 2}, {"device_id": 2, "function_desc": "less", "function_title": "less", "status": 2}], "image_path": "vfx", "status_id": 2, "statuss": {"status_desc": "device is off", "status_title": "off"}}]}
''';
结果:
cooler pomp less up panke pomp less
大多数问题是由数据模型的缺陷引起的。在此示例中,使用了以下数据模型。
class Devices {
final String deviceDesc;
final String deviceTitle;
final List<Functions> functions;
final String imagePath;
final int statusId;
final Statuss statuss;
Devices(
{this.deviceDesc,
this.deviceTitle,
this.functions,
this.imagePath,
this.statusId,
this.statuss});
factory Devices.fromJson(Map<String, dynamic> json) {
return Devices(
deviceDesc: json['device_desc'] as String,
deviceTitle: json['device_title'] as String,
functions: _toObjectList(json['functions'], (e) => Functions.fromJson(e)),
imagePath: json['image_path'] as String,
statusId: json['status_id'] as int,
statuss: _toObject(json['statuss'], (e) => Statuss.fromJson(e)),
);
}
Map<String, dynamic> toJson() {
return {
'device_desc': deviceDesc,
'device_title': deviceTitle,
'functions': _fromList(functions, (e) => e.toJson()),
'image_path': imagePath,
'status_id': statusId,
'statuss': statuss?.toJson(),
};
}
}
class Functions {
final int deviceId;
final String functionDesc;
final String functionTitle;
final int status;
Functions(
{this.deviceId, this.functionDesc, this.functionTitle, this.status});
factory Functions.fromJson(Map<String, dynamic> json) {
return Functions(
deviceId: json['device_id'] as int,
functionDesc: json['function_desc'] as String,
functionTitle: json['function_title'] as String,
status: json['status'] as int,
);
}
Map<String, dynamic> toJson() {
return {
'device_id': deviceId,
'function_desc': functionDesc,
'function_title': functionTitle,
'status': status,
};
}
}
class Response1 {
final List<Devices> devices;
Response1({this.devices});
factory Response1.fromJson(Map<String, dynamic> json) {
return Response1(
devices: _toObjectList(json['devices'], (e) => Devices.fromJson(e)),
);
}
Map<String, dynamic> toJson() {
return {
'devices': _fromList(devices, (e) => e.toJson()),
};
}
}
class Statuss {
final String statusDesc;
final String statusTitle;
Statuss({this.statusDesc, this.statusTitle});
factory Statuss.fromJson(Map<String, dynamic> json) {
return Statuss(
statusDesc: json['status_desc'] as String,
statusTitle: json['status_title'] as String,
);
}
Map<String, dynamic> toJson() {
return {
'status_desc': statusDesc,
'status_title': statusTitle,
};
}
}
List _fromList(data, Function(dynamic) toJson) {
if (data == null) {
return null;
}
var result = [];
for (var element in data) {
var value;
if (element != null) {
value = toJson(element);
}
result.add(value);
}
return result;
}
T _toObject<T>(data, T Function(Map<String, dynamic>) fromJson) {
if (data == null) {
return null;
}
return fromJson(data as Map<String, dynamic>);
}
List<T> _toObjectList<T>(data, T Function(Map<String, dynamic>) fromJson) {
if (data == null) {
return null;
}
var result = <T>[];
for (var element in data) {
T value;
if (element != null) {
value = fromJson(element as Map<String, dynamic>);
}
result.add(value);
}
return result;
}
/*
Response1:
"devices": List<Devices>
Devices:
"device_desc": String
"device_title": String
"functions": List<Functions>
"image_path": String
"status_id": int
"statuss": Statuss
Functions:
"device_id": int
"function_desc": String
"function_title": String
"status": int
Statuss:
"status_desc": String
"status_title": String
*/