Flutter 颤振:类型为'的值;列表<;类型>';can';不能分配给类型为';列表<;类型>';
我想从这个json文件中获取和打印数据:Flutter 颤振:类型为'的值;列表<;类型>';can';不能分配给类型为';列表<;类型>';,flutter,Flutter,我想从这个json文件中获取和打印数据: [{"id": "76d751584e134ebf854bebda8998334b", "data": {"timestamp": "15/05/2021-13:08:38", "temperature": 21.9, "pressure": 1007.4342535, "humidity": 4
[{"id": "76d751584e134ebf854bebda8998334b", "data": {"timestamp": "15/05/2021-13:08:38", "temperature": 21.9, "pressure": 1007.4342535, "humidity": 43.994442131}}, {"id": "6188e169eeda4547b3e87414d50664df", "data": {"timestamp": "15/05/2021-15:08:38", "temperature": 22.28, "pressure": 1006.47539066, "humidity": 46.1434366089}}, {"id": "4eb75a12fd6c4eb8a94b20106aab4e2a", "data": {"timestamp": "15/05/2021-17:08:38", "temperature": 22.71, "pressure": 1006.52941164, "humidity": 47.7676641555}}]
这是我的颤振密码女巫应该做的工作:
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
class SensorData with ChangeNotifier {
//final id;
final timestamp;
final temperature;
final pressure;
final humidity;
SensorData({
//@required this.id,
@required this.timestamp,
@required this.temperature,
@required this.pressure,
@required this.humidity,
});
factory SensorData.fromJson(Map<String, dynamic> json) {
return new SensorData(
//id: json['id'] as String,
timestamp: json['timestamp'] as String,
temperature: json['temperature'] as double,
pressure: json['pressure'] as double,
humidity: json['humidity'] as double,
);
}
}
class App extends StatefulWidget {
@override
_AppState createState() => _AppState();
}
class _AppState extends State<App> {
Future<List<SensorData>> fetchSensorDatas() async {
final http.Response response = await http.get(Uri.http(<my_API_url>));
var responseJson = json.decode(response.body);
return (responseJson['data'] as List)
.map((p) => SensorData.fromJson(p))
.toList();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: new Container(
child: new Column(
children: [
new Container(
height: 200,
),
new ListView(
children: <Widget>[
new FutureBuilder<List<SensorData>>(
future: fetchSensorDatas(),
builder: (context, snapshot) {
if (snapshot.hasData){
List<SensorData> posts = snapshot.data;
return new Column(
children: posts.map((post) => new Column(
children: <Widget>[
new Text(post.temperature),
],
)).toList()
);
}
else if(snapshot.hasError)
{
return snapshot.error;
}
return new Center(
child: new Column(
children: <Widget>[
new Padding(padding: new EdgeInsets.all(50.0)),
new CircularProgressIndicator(),
],
),
);
},
),
],
),
],
),
),
);
}
}
导入'dart:convert';
进口“包装:颤振/材料.省道”;
将“package:http/http.dart”导入为http;
使用ChangeNotifier初始化SensorData{
//最终id;
最终时间戳;
最终温度;
最终压力;
最终湿度;
传感器数据({
//@需要这个.id,
@需要这个时间戳,
@需要这个温度,
@需要这个压力,
@需要这个,湿度,
});
factory SensorData.fromJson(映射json){
返回新的传感器数据(
//id:json['id']作为字符串,
timestamp:json['timestamp']作为字符串,
温度:json['temperature']为双精度,
压力:json['pressure']为双精度,
湿度:json[“湿度”]为双倍,
);
}
}
类应用程序扩展StatefulWidget{
@凌驾
_AppState createState();
}
类_AppState扩展了状态{
未来的fetchSensorDatas()异步{
final http.Response-Response=wait http.get(Uri.http());
var responseJson=json.decode(response.body);
返回(responseJson['data']作为列表)
.map((p)=>SensorData.fromJson(p))
.toList();
}
@凌驾
小部件构建(构建上下文){
返回脚手架(
主体:新容器(
子:新列(
儿童:[
新容器(
身高:200,
),
新列表视图(
儿童:[
新未来建设者(
future:fetchSensorDatas(),
生成器:(上下文,快照){
if(snapshot.hasData){
List posts=snapshot.data;
返回新列(
子项:posts.map((post)=>新列(
儿童:[
新文本(后温度),
],
))托利斯先生()
);
}
else if(snapshot.hasrerror)
{
返回snapshot.error;
}
返回新中心(
子:新列(
儿童:[
新填充(填充:新边集。全部(50.0)),
新的CircularProgressIndicator(),
],
),
);
},
),
],
),
],
),
),
);
}
}
我有两个错误:
- snapshot.data返回我“无法将'List'类型的值分配给'List'类型的变量。”
- snapshot.error返回我“返回类型‘Object’不是闭合上下文所要求的‘Widget’。”
fetchSensorDatas
方法中。由于responseJson
是一个映射
,因此每次从它访问密钥时,都有可能该密钥不存在,并且它将返回null(因此返回可为null的类型列表?
)。如果确定密钥存在,则可以执行以下操作:
final List data = responseJson['data']! as List;
return data.map((p) => SensorData.fromJson(p)).toList();
snapshot.error返回我“返回类型‘Object’不是闭合上下文所要求的‘Widget’。”
这是因为您在FutureBuilder
的builder
参数中返回了多个类型,因此它的返回类型将是所有返回类型的通用ascestor,在本例中为对象
。请注意,在第一个条件中返回一个列
,在第二个条件中返回一个错误
,在第三个条件中返回一个中心
。您可以用一些Wigdet
替换第二个返回:
else if(snapshot.hasrerror){
//备选方案1:返回带有错误消息的文本小部件
返回文本(snapshot.error?.toString()??“”);
//备选方案2:打印错误消息并返回一个空小部件
打印(快照错误);
返回SizedBox.shrink();
//备选方案3:显示说明性小部件发生错误的用户
返回文本(“发生错误”);
//备选方案4:重新显示错误
抛出快照错误;
}
我想出来了
首先,我的模型很差,所以我重写如下:
import 'dart:convert';
List<SensorData> sensorDataFromJson(String str) => List<SensorData>.from(json.decode(str).map((x) => SensorData.fromJson(x)));
String sensorDataToJson(List<SensorData> data) => json.encode(List<dynamic>.from(data.map((x) => x.toJson())));
class SensorData {
SensorData({
required this.id,
required this.data,
});
String id;
Data data;
factory SensorData.fromJson(Map<String, dynamic> json) => SensorData(
id: json["id"],
data: Data.fromJson(json["data"]),
);
Map<String, dynamic> toJson() => {
"id": id,
"data": data.toJson(),
};
}
class Data {
Data({
required this.timestamp,
required this.temperature,
required this.pressure,
required this.humidity,
});
String timestamp;
double temperature;
double pressure;
double humidity;
factory Data.fromJson(Map<String, dynamic> json) => Data(
timestamp: json["timestamp"],
temperature: json["temperature"].toDouble(),
pressure: json["pressure"].toDouble(),
humidity: json["humidity"].toDouble(),
);
Map<String, dynamic> toJson() => {
"timestamp": timestamp,
"temperature": temperature,
"pressure": pressure,
"humidity": humidity,
};
}
导入'dart:convert';
List sensorDataFromJson(String str)=>List.from(json.decode(str.map)(x)=>SensorData.fromJson(x));
字符串sensorDataToJson(List data)=>json.encode(List.from(data.map((x)=>x.toJson()));
类传感器数据{
传感器数据({
需要这个.id,
需要这个数据,
});
字符串id;
数据;
factory SensorData.fromJson(映射json)=>SensorData(
id:json[“id”],
data:data.fromJson(json[“data”]),
);
映射到JSON()=>{
“id”:id,
“data”:data.toJson(),
};
}
类数据{
资料({
需要这个时间戳,
需要这个温度,
需要这个压力,
需要这个,湿度,
});
字符串时间戳;
双温;
双重压力;
双湿度;
工厂数据.fromJson(映射json)=>数据(
时间戳:json[“时间戳”],
温度:json[“温度”].toDouble(),
压力:json[“压力”].toDouble(),
湿度:json[“湿度”].toDouble(),
);
映射到JSON()=>{
“时间戳”:时间戳,
“温度”:温度,
"压力":压力,,
“湿度”:湿度,
};
}
那么我有一个方法
Future<List<SensorData>> getSensorDatas() async {
final response = await http.get(Uri.http('192.168.1.3:5000', '/pigarden/'));
return sensorDataFromJson(response.body);
}
FutureBuilder<List<SensorData>>(
future: SensorDatasRepository().getSensorDatas(),
builder: (context, snapshot) {
if (snapshot.hasError) {
showDialog(
context: context,
builder : (BuildContext context) => const AlertDialog(
title: Text("Error"),
content: Text('An error has occured...'),
),
);
} else if (snapshot.hasData) {
return ListView.builder(
itemCount: snapshot.data!.length,
itemBuilder: (context, index) => ListTile(
title: Text(snapshot.data![index].id),
subtitle: Text(
snapshot.data![index].data.temperature.toString(),
softWrap: false,
overflow: TextOverflow.ellipsis,
),
),
);
}
return Center(
child: CircularProgressIndicator(),
);
},
),