如何在 Flutter 中设置定时器来定期更新 API 数据

Posted

技术标签:

【中文标题】如何在 Flutter 中设置定时器来定期更新 API 数据【英文标题】:How to set a timer to update API data periodically in Flutter 【发布时间】:2020-09-09 05:39:16 【问题描述】:

我从 API 获取数据并将其加载到列表视图。我的列表视图显示查询结果没有任何问题。我想通过定期从 API 获取数据来更新我的列表视图。最好的方法是什么?

这就是我在主屏幕的 initState 中调用 API 方法的方式。

@override
  void initState() 
    // TODO: implement initState
    super.initState();
    _fixtureData = getFixture();
  

  Future<List<Fixtures>> getFixture() async 
    fixtureList = await FootballApi.getFixtureData();
    return fixtureList;
  

这是我在主屏幕中通过 FutureBuilder 呈现 ListView 的代码。

              FutureBuilder<List<Fixtures>>(
                  future: _fixtureData,
                  builder: (context, snapshot) 
                    if (snapshot.hasData) 
                      fixtureList = snapshot.data;

                      return AppListView(
                        matchList: fixtureList,
                        //callback function brings the matchCounter value from ListView class
                        onChange: (value) 
                          setState(() 
                            matchCounter = value;
                          );
                        ,
                        finalBetList: (value) 
                          setState(() 
                            betList = value;
                          );
                        ,
                      );
                    
                    return Column(
                      mainAxisAlignment: MainAxisAlignment.center,
                      crossAxisAlignment: CrossAxisAlignment.center,
                      children: <Widget>[
                        SizedBox(
                          child: CircularProgressIndicator(),
                          width: 60,
                          height: 60,
                        ),
                        const Padding(
                          padding: EdgeInsets.only(top: 16),
                          child: Text(
                            'Awaiting result...',
                            style: TextStyle(color: Colors.white),
                          ),
                        )
                      ],
                    );
                  ,
                ),

而这个 sn-p 就是我调用的 API 方法。

static Future<List<Fixtures>> getFixtureData() async 
    Map<String, String> queryParameters = 
      'league': '79',
      'next': '5',
    ;


    http.Response response = await http.get(
      getUrl('fixtures', queryParameters),
      headers: requestHeaders,
    );

    if (response.statusCode == 200) 
      String data = response.body;
      List<dynamic> result = jsonDecode(data)['response'];

      for (int i = 0; i < result.length; i++) 
        Fixtures fixture = Fixtures();

        fixture.leagueID = jsonDecode(data)['response'][i]['league']['id'];
        fixture.country = jsonDecode(data)['response'][i]['league']['country'];
        fixture.leagueName = jsonDecode(data)['response'][i]['league']['name'];
        fixture.fixtureID = jsonDecode(data)['response'][i]['fixture']['id'];

        //get Odds to match with fixtures by fixtureID
        await getOddsData(fixture.fixtureID);

        fixture.dateTime =
            DateTime.parse(jsonDecode(data)['response'][i]['fixture']['date']);
        fixture.homeTeam =
            jsonDecode(data)['response'][i]['teams']['home']['name'];
        fixture.awayTeam =
            jsonDecode(data)['response'][i]['teams']['away']['name'];
        fixture.status =
            jsonDecode(data)['response'][i]['fixture']['status']['long'];
        fixture.homeGoals = jsonDecode(data)['response'][i]['goals']['home'];
        fixture.awayGoals = jsonDecode(data)['response'][i]['goals']['away'];
        fixture.htScoreHome =
            jsonDecode(data)['response'][i]['score']['halftime']['home'];
        fixture.htScoreAway =
            jsonDecode(data)['response'][i]['score']['halftime']['away'];
        fixture.ftScoreHome =
            jsonDecode(data)['response'][i]['score']['fulltime']['home'];
        fixture.ftScoreAway =
            jsonDecode(data)['response'][i]['score']['fulltime']['away'];

        if (oddsList.length > 0) 
          for (int j = 0; j < oddsList.length; j++) 
            if (oddsList[j].fixtureID == fixture.fixtureID) 
              fixture.homeOdds = oddsList[j].homeOdds;
              fixture.drawOdds = oddsList[j].drawOdds;
              fixture.awayOdds = oddsList[j].awayOdds;
              fixture.bookmakerName = oddsList[j].bookmakerName;
              FootballApi.fixtureList.add(
                  fixture);
            
          
        
      
     else 
      print('statusCode: ' + response.statusCode.toString());
    

    return FootballApi.fixtureList;
  

【问题讨论】:

您可以使用Timer 定期调用一个函数来获取数据,然后更新小部件的state,从而使用从API 获取的新数据进行重建 【参考方案1】:

计时器将是一个不错的选择。 一旦你的状态被初始化就启动一个计时器,并在小部件被释放后释放。 在计时器内部,您为小部件调用 API 和 setState

 @override
 void initState() 
   getFixture();
   _timer = new Timer.periodic(Duration(seconds: 30), 
   (_) => getFixture());
   super.initState();
 

 @override
 void dispose() 
   _timer.cancel();
   super.dispose();
 

【讨论】:

当我在 initState 中设置定时器时,它也在等待 30 秒来显示初始数据。我想用初始数据渲染列表视图,例如每 5 分钟更新一次。我应该在哪里设置计时器? 让定时器只在那个地方。但在定时器调用 getFixture() 之前 谢谢。另外,我应该在 setSate 中调用 getFixture 来重新渲染屏幕,对吗?我的 initState 代码是这样的; void initState() _fixtureData = getFixture(); _timer = Timer.periodic(Duration(seconds: 30), (Timer timer) setState(() _fixtureData = getFixture(); ); ); super.initState();

以上是关于如何在 Flutter 中设置定时器来定期更新 API 数据的主要内容,如果未能解决你的问题,请参考以下文章

如何在android中设置计时器?

如何在 Flutter 中设置工作日多天的本地通知?

如何在Windows系统中设置Python程序定时运行

如何在 Flutter 中设置不同的 firebase 环境

如何在 Xcode 中设置 Flutter 构建选项

如何在 Flutter 中设置主屏幕的背景颜色?