Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/xpath/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Flutter 颤振:类型为'的值;列表<;类型>';can';不能分配给类型为';列表<;类型>';_Flutter - Fatal编程技术网

Flutter 颤振:类型为'的值;列表<;类型>';can';不能分配给类型为';列表<;类型>';

Flutter 颤振:类型为'的值;列表<;类型>';can';不能分配给类型为';列表<;类型>';,flutter,Flutter,我想从这个json文件中获取和打印数据: [{"id": "76d751584e134ebf854bebda8998334b", "data": {"timestamp": "15/05/2021-13:08:38", "temperature": 21.9, "pressure": 1007.4342535, "humidity": 4

我想从这个json文件中获取和打印数据:

[{"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’。”
我哪里做错了

非常感谢

snapshot.data返回我“无法将'List'类型的值分配给'List'类型的变量。”

问题出在
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(),
          );
        },
      ),