检索到的数据未显示在小部件中

时间:2018-12-06 16:36:49

标签: android asynchronous flutter hybrid-mobile-app

我的服务器上托管了一个json文件,如下所示。

{
  "score": "23/6"
}

分数总是在更新,我希望我的flutter应用程序显示实时分数。

Flutter代码在这里:

import 'package:flutter/material.dart';
import 'dart:async';
import 'dart:convert';
import 'package:http/http.dart' as http;
var json_score;
var json_overs;

class livee extends StatefulWidget {
  @override
  _liveeState createState() => _liveeState();
}

class _liveeState extends State<livee> {

  final String url = "path_to_my_json";

  @override
  void initState(){
    super.initState();
    this.getJsonData();
  }

  Future<String> getJsonData() async{
    http.Response response = await http.get(
      Uri.encodeFull(url),
      headers: {"Accept" : "application/json"}
    );


     var data = jsonDecode(response.body);
     json_score = data['score'];


     print(json_score.toString());

  }

  @override
  Widget build(BuildContext context) {

    //Status bar
    final status = Text(
        "XYZ College",
        style: TextStyle(fontSize: 12.0, fontWeight: FontWeight.bold),
        textAlign: TextAlign.center);


    final score = Container(
      alignment: Alignment(0.0, 0.0),
      child: Text(json_score.toString(),
          style: TextStyle(
              fontSize: 50.0,
              color: Colors.blueAccent,
              fontWeight: FontWeight.bold)),
    );


    return new Container(
      color: Colors.white,
      height: MediaQuery.of(context).size.height,
      child: ListView(
        shrinkWrap: true,
        children: <Widget>[
          livestatus,
          score,

        ],
      ),
    );
  }
}

我设法将分数添加到我的应用程序中,但是它需要刷新应用程序以显示更新的分数。我该如何间隔更新分数?

1 个答案:

答案 0 :(得分:2)

您在这里缺少一些东西。

首先,您已经使var json_score;var json_overs;本质上是全局变量,我敢肯定这不是您的意图。除非您有非常特殊的原因,否则通常不应在类之外具有(非const)变量,因为它们将在对象的所有实例之间共享。

此外,Flutter的有状态小部件的工作方式是,当您更改其状态时,Flutter引擎会检查该对象是否已更改,并且仅在该对象已更改时才进行重建。如果变量不在对象中,则对象将不会更改,因此不会重建。

您缺少的另一件事是,每次更改State对象的“状态”时,您都应该调用setState(...)并对该函数中的状态进行突变。

我已经对您的代码进行了一些修正:

import 'dart:async';
import 'dart:convert';

import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;

class Livee extends StatefulWidget {
  @override
  _LiveeState createState() => _LiveeState();
}

class _LiveeState extends State<Livee> {
  final String url = "path_to_my_json";

  var jsonScore;
  var jsonOvers;

  @override
  void initState() {
    super.initState();
    this.getJsonData();
  }

  Future<String> getJsonData() async {
    http.Response response = await http.get(Uri.encodeFull(url), headers: {"Accept": "application/json"});

    var data = jsonDecode(response.body);

    setState(() => jsonScore = data['score']);

    print(jsonScore.toString());
  }

  @override
  Widget build(BuildContext context) {
    //Status bar
    final status =
        Text("XYZ College", style: TextStyle(fontSize: 12.0, fontWeight: FontWeight.bold), textAlign: TextAlign.center);

    final score = Container(
      alignment: Alignment(0.0, 0.0),
      child: Text(jsonScore.toString(),
          style: TextStyle(fontSize: 50.0, color: Colors.blueAccent, fontWeight: FontWeight.bold)),
    );

    return new Container(
      color: Colors.white,
      height: MediaQuery.of(context).size.height,
      child: ListView(
        shrinkWrap: true,
        children: <Widget>[
          livestatus,
          score,
        ],
      ),
    );
  }
}

这应该对您更有效,尽管我个人建议您将分数检索分成一个不同的类,然后通过StreamBuilder将其连接到您的类上,而不是如何进行,但这更多复杂。

我还有几句话与问题无关,但与您的代码有关。

  1. 当您在StackOverflow上发帖时,如果将代码缩减为仅遇到的问题,将很有帮助。这段代码没那么长,所以解析起来并不难,但是如果您遇到一个复杂的问题,那么它可能就是一个问题(而且问题越好,就越有可能迅速而有帮助地回答它= D )
  2. 我建议阅读并关注代码中的the dart style guide和/或flutter style guide。遵循标准将使您的代码更干净,其他人也更容易上手,这将使您与其他人一起工作变得更容易(即使您当前的项目只适合您)。
  3. 您似乎略微错过了抖动的一些基本概念。他们在flutter.io website上有一些非常不错的教程-从长远来看,如果您花一些时间阅读并编写代码以跟随教程,那么您可能会节省时间和头痛这样很多。 This is the one尤其说明了有状态的小部件的工作方式。