如何从api排序数据?

时间:2019-01-24 17:42:15

标签: dart flutter json.net

有两个下拉按钮,其中包含国家/地区和运动类型的列表。如果在他们身上选择了放荡不羁,则需要向国家和/或体育节目显示带有联赛的listTile;如果在他们身上没有任何选择,则显示所有联赛。

但是我得到了

  

Dart错误:未处理的异常:    在dispose()之后调用setState():_SportLigPageState#b5830(生命周期状态:已终止,未安装)    如果您看到小部件树(例如),就会发生这种情况。拨打电话时可能发生此错误。处置()回调。有必要确保该对象仍在树中。   如果不是,则可以是存储卡。为避免内存泄漏,请考虑处理()。

Api与联盟:https://www.thesportsdb.com/api/v1/json/1/all_leagues.php

class LigList extends StatefulWidget {
  @override
  _LigListState createState() => _LigListState();
}

class _LigListState extends State<LigList> {
  String sport;
  String country;
  List data;
  Future<String> getJsonData() async {
    http.Response response;
    if (sport != null) {
      if (country != null) response  = await http
          .get(Uri.encodeFull('https://www.thesportsdb.com/api/v1/json/1/all_leagues.php?c=$sport&s=$country'), headers: {"Accept": "application/json"});
      else  response  = await http
          .get(Uri.encodeFull('https://www.thesportsdb.com/api/v1/json/1/all_leagues.php?c=$sport'), headers: {"Accept": "application/json"});}
    else if (country == null){ response  = await http
        .get(Uri.encodeFull('https://www.thesportsdb.com/api/v1/json/1/all_leagues.php'), headers: {"Accept": "application/json"});}
    else  response  = await http
          .get(Uri.encodeFull('https://www.thesportsdb.com/api/v1/json/1/all_leagues.php?c=$country'), headers: {"Accept": "application/json"});


      var convertDatatoJson = json.decode(response.body);
      data = convertDatatoJson['leagues'];
    return "Success";
  }

  static const menuItems = countriesList;
  final List<DropdownMenuItem<String>> _dropDownItems = menuItems
      .map((String CountruValue) =>
      DropdownMenuItem<String>(
        value: CountruValue,
        child: Text(CountruValue),
      ),
  ).toList();

  @override
  Widget build(BuildContext context) {
    return Container(
      child: Center(
        child: Column(children: <Widget>[
          FutureBuilder(
              builder: (BuildContext context, AsyncSnapshot snapshot) {
                return DropdownButton(
                  value: country,
                  hint: Text("Choose a countre league of which you want to find"),
                  items:  _dropDownItems,
                  onChanged: (value) {
                    country = value;
                    print(country);
                    setState(() {});
                  },
                );}),
          SizedBox(width: 5),
          FutureBuilder(
              future: _getSports(),
              builder: (BuildContext context, AsyncSnapshot snapshot) {
                return snapshot.hasData
                    ? DropdownButton(
                  value: sport,
                  hint: Text("Choose a sport league of which you want to find"),
                  items: snapshot.data,
                  onChanged: (value) {
                    sport = value;
                    print(sport);
                    setState(() {});
                  },
                )
                    : Padding(
                    padding: EdgeInsets.symmetric(vertical: 20),
                    child: CircularProgressIndicator());
              }),
          Flexible(
              child:FutureBuilder(
                  future: getJsonData(),
                  builder: (BuildContext context, AsyncSnapshot snapshot) {
                    return ListView.separated(
                        itemCount: data == null ? 0 : data.length,
                        itemBuilder: (BuildContext context, int i) {
                          return Container(
                              child: Center(
                                  child: Column(
                                      crossAxisAlignment: CrossAxisAlignment
                                          .stretch,
                                      children: <Widget>[
                                        ListTile(
                                          title: Text(data[i]['strLeague']),
                                          subtitle: Text(
                                              data[i]['strSport']),
                                          onTap: () {
                                            Navigator.push(
                                                context,
                                                new MaterialPageRoute(
                                                    builder: (
                                                        BuildContext context) =>
                                                    new ComandListScreen()
                                                  // (data[i])
                                                ));
                                          },
                                        ),
                                      ]
                                  )
                              )
                          );
                        });
                  }))
        ]),
      ),
    );
  }
}

非常感谢您的协助。

1 个答案:

答案 0 :(得分:0)

您的代码有很多错误。代码中的第一个孩子被包装在FutureBuilder中,但是您没有使用任何Future功能。

 FutureBuilder(
   builder: (BuildContext context, AsyncSnapshot snapshot) {
      return DropdownButton(
        value: country,
        hint: Text("Choose a countre league of which you want to find"),
        items:  _dropDownItems,
        onChanged: (value) {
           country = value;
           print(country);
           setState(() {}); // Remove this line
         },
  );}),

除此之外,您还可以在onChanged回调中随机调用setState(),而其中没有任何内容。我建议您从FutureBuilder中取出该小部件,然后单独使用DropdownButton。

然后也在此行

itemCount: data == null ? 0 : data.length,

您正在使用的数据是在将来调用该数据时设置的。您可能需要阅读有关如何正确使用FutureBuilder小部件的信息。只需从_getJsonData()Future中返回数据对象,因为无论如何它总是返回“ Success”。从Future返回您想要的列表,然后使用snapshot.data

进行访问

最后,实际上只有一个setState调用,因此将其删除就可以了。我的假设是您正在打电话或离开时还有一些其他处置,应用程序崩溃。需要更多信息来解决,但是您必须修复使用Futures和Future构建器的方式,以便我们确保不是因为潜在线程返回并在离开视图后设置状态而造成的。在。