在我的Flutter 应用程序上,我试图显示更新的数据.我成功地从气象API手动获取了数据.但我需要每隔5秒不断地抓取数据.所以它应该会自动更新.下面是我的代码:

class MyApp extends StatelessWidget {

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Sakarya Hava',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: Scaffold(
        appBar: AppBar(
          title: Text('Sakarya Hava'),
        ),
        body: Center(
          child: FutureBuilder<SakaryaAir>(
            future: getSakaryaAir(), //sets the getSakaryaAir method as the expected Future
            builder: (context, snapshot) {
              if (snapshot.hasData) { //checks if the response returns valid data
                return Center(
                  child: Column(
                    children: <Widget>[
                      Text("${snapshot.data.temp}"), //displays the temperature
                      SizedBox(
                        height: 10.0,
                      ),
                      Text(" - ${snapshot.data.humidity}"), //displays the humidity
                    ],
                  ),
                );
              } else if (snapshot.hasError) { //checks if the response throws an error
                return Text("${snapshot.error}");
              }
              return CircularProgressIndicator();
            },
          ),
        ),
      ),
    );
  }


  Future<SakaryaAir> getSakaryaAir() async {
    String url = 'http://api.openweathermap.org/data/2.5/weather?id=740352&APPID=6ccf09034c9f8b587c47133a646f0e8a';
    final response =
    await http.get(url, headers: {"Accept": "application/json"});


    if (response.statusCode == 200) {
      return SakaryaAir.fromJson(json.decode(response.body));
    } else {
      throw Exception('Failed to load post');
    }
  }
}

我发现这样一个片段可以从中受益:

// runs every 5 second
Timer.periodic(new Duration(seconds: 5), (timer) {
   debugPrint(timer.tick);
});

可能我需要用这段代码包装并调用FutureBuilder,但我不能理解如何做到这一点.

推荐答案

您可以重构FutureBuilder以使用Future变量,而不是调用FutureBuilder中的方法.这需要您使用StatefulWidget,您可以在initState中设置future ,然后拨打setState进行更新.

因此,您有一个future 的变量字段,如下所示:

Future< SakaryaAir> _future;

所以你的initState应该是这样的:

@override
  void initState() {
    super.initState();
    setUpTimedFetch();
  }

其中setUpTimedFetch定义为

  setUpTimedFetch() {
    Timer.periodic(Duration(milliseconds: 5000), (timer) {
      setState(() {
        _future = getSakaryaAir();
      });
    });
  }

最后,您的FutureBuilder将更改为:

FutureBuilder<SakaryaAir>(
          future: _future,
          builder: (context, snapshot) {
            //Rest of your code
          }),

这是一个DartPad演示:https://dartpad.dev/2f937d27a9fffd8f59ccf08221b82be3

Dart相关问答推荐

将所有内容放在有序组中,但将括号中的字符组合在一起

从 Dart 中的工厂构造函数返回 null 是否可以接受?

Flutter 使用拖动和按钮单击扩展 TextField

我需要在使用之前将我的 Dart 包发布到 pub.dartlang.org 吗?

自定义声音推送通知不起作用

在 Flutter 中保持响应的同时制作持久的背景图像

在 Dart 中将对象推入数组

Dart:Streams与 ValueNotifiers

停止音频循环(audioplayers 包)

从real mobile浏览器访问Flatter localhost

有没有更好的方法来解析 Dart 中的 int

在 TextInputType 更改后控制器重置的 Flutter TextField

Flutter-当文本字段有焦点时隐藏提示文本

Dart null 安全性不适用于类字段

Dart:并行处理传入的 HTTP 请求

如何构建具有多个视图的复杂 Web UI 应用程序?

如何使用 Dart 列出目录的内容?

如何在 Dart 中生成唯一 id

如何在 Dart 中创建私有变量?

如何在 Dart 中获取时间戳?