在 Flutter 中以间隔自动获取 Api 数据 [英] Fetch Api Data Automatically with Interval in Flutter

查看:50
本文介绍了在 Flutter 中以间隔自动获取 Api 数据的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的 flutter 应用程序中,我试图显示更新数据.我成功地手动从天气 api 获取数据.但我需要每 5 秒不断地抓取数据.所以它应该自动更新.这是我在 Flutter 中的代码:

class MyApp 扩展 StatelessWidget {@覆盖小部件构建(BuildContext 上下文){返回 MaterialApp(title: '萨卡里亚哈瓦',主题:主题数据(主要色板:Colors.blue,),主页: 脚手架(应用栏:应用栏(标题:文本('萨卡里亚哈瓦'),),身体:中心(孩子:FutureBuilder<SakaryaAir>(future: getSakaryaAir(),//将getSakaryaAir方法设置为预期的Future构建器:(上下文,快照){if (snapshot.hasData) {//检查响应是否返回有效数据返回中心(孩子:列(孩子们:<小部件>[Text("${snapshot.data.temp}"),//显示温度大小盒(高度:10.0,),Text(" - ${snapshot.data.humity}"),//显示湿度],),);} else if (snapshot.hasError) {//检查响应是否抛出错误return Text("${snapshot.error}");}返回 CircularProgressIndicator();},),),),);}未来<SakaryaAir>getSakaryaAir() 异步 {字符串 url = 'http://api.openweathermap.org/data/2.5/weather?id=740352&APPID=6ccf09034c9f8b587c47133a646f0e8a';最后回复=await http.get(url, headers: {"Accept": "application/json"});if (response.statusCode == 200) {返回 SakaryaAir.fromJson(json.decode(response.body));} 别的 {throw Exception('加载帖子失败');}}}

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

//每 5 秒运行一次Timer.periodic(new Duration(seconds: 5), (timer) {debugPrint(timer.tick);});

可能我需要用这个代码片段来包装和调用 FutureBuilder,但我无法理解如何去做.

解决方案

您可以重构您的 FutureBuilder 以使用 Future 变量,而不是调用 中的方法>FutureBuilder.这将需要您使用 StatefulWidget 并且您可以在 initState 中设置未来并通过调用 setState 来更新它.

所以你有一个未来的变量字段,比如:

未来<萨卡里亚空气>_未来;

所以你的 initState 看起来像这样:

@override无效的初始化状态(){super.initState();setUpTimedFetch();}

其中 setUpTimedFetch 定义为

 setUpTimedFetch() {Timer.periodic(持续时间(毫秒:5000),(计时器){设置状态((){_future = getSakaryaAir();});});}

最后,您的 FutureBuilder 将更改为:

FutureBuilder(未来:_未来,构建器:(上下文,快照){//其余代码}),

这是一个 DartPad 演示:https://dartpad.dev/2f937d27a9fffd8f59ccf08221b>82p

On my flutter application I am trying to show updating data. I am successful in getting data from weather api manually. But I need to constantly grab data every 5 seconds. So it should be updated automatically. Here is my code in Flutter :

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');
    }
  }
}

I found such a snippet to benefit from :

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

Probably I need to wrap and call FutureBuilder with this snippet but I was not able to understand how to do it.

You can refactor your FutureBuilder to use a Future variable instead of calling the method in the FutureBuilder. This would require you to use a StatefulWidget and you can set up the future in your initState and update it by calling setState.

So you have a future variable field like:

Future< SakaryaAir> _future;

So your initState would look like this :

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

where setUpTimedFetch is defined as

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

Finally, your FutureBuilder will be changed to:

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

Here is a DartPad demo: https://dartpad.dev/2f937d27a9fffd8f59ccf08221b82be3

这篇关于在 Flutter 中以间隔自动获取 Api 数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆