使用FutureBuilder和ListView.builder初始化应用,并在每个ListItem中都有一个onClick吗?

时间:2019-05-06 20:26:11

标签: asynchronous flutter state future

我正在使用Flutter构建应用程序,并且在使用FutureBuilder时遇到了问题。情况是我在App中的HomePage应该向我的服务器发出请求并获得一些Json。对getData-Method的调用发生在主屏幕的构建方法中(不确定这是否正确)。 build-Method中的下一个调用具有快照并构建ListView。

问题出在这里

每次我单击一个按钮或转到另一个屏幕时,都会触发Future Builder!这意味着我有很多无用的API调用。

这是问题:

要让Future Builder仅在我进入主屏幕时才运行,我需要更改什么?

class HomeState extends State<Home> {

  int count = 0;

  final homeScaffoldKey = GlobalKey<ScaffoldState>();

  List compList = new List();

  Future<List> getData() async {
    final response = await http.get(
      Uri.encodeFull("http://10.0.2.2:5000/foruser"),
      headers: {
        "Authorization":
            "JWT eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHAiOjE1NTk2NDM4ODcsImlhdCI6MTU1NzA1MTg4NywibmJmIjoxNTU3MDUxODg3LCJpZGVudGl0eSI6MX0.OhuUgX9IIYFX7u0o_6MXlrMYwk7oMCywlmHLw-vbNSY",
        "charset": "utf-8"
      },
    );

    if (response.statusCode == 200) {
      compList = jsonDecode(response.body);
      List<Comp> result = [];
      count++;
      for (var c in compList) {
        Comp comp = Comp.fromJson(c);
        result.add(comp);
      }
      return result;
    } else {
      throw Exception('Failed to load');
    }
  }

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
        backgroundColor: Colors.white10,
        body: Stack(
          children: <Widget>[
            new Container(
              child: FutureBuilder(
                future: getData(),
                builder: (BuildContext context, AsyncSnapshot snapshot) {
                  if (snapshot.connectionState == ConnectionState.done) {
                    if (snapshot.data == null) {
                      return new Container(
                        child: Text("whoops"),
                      );
                    }
                    if (snapshot.hasData) {
                      if (snapshot.data != null) {
                        if (snapshot.data.toString() == "[]") {
                          print("no comps - called API: $count");
                          return new ListView(
                            key: Key("1"),
                            children: <Widget>[
                              new Column(
                                mainAxisSize: MainAxisSize.max,
                                children: <Widget>[
                                  SizedBox(
                                    height: 30.0,
                                  ),
                                  Card(
                                    color: Colors.blue,
                                    child: Column(
                                      mainAxisSize: MainAxisSize.min,
                                      children: <Widget>[
                                        ListTile(
                                          title: Text(
                                            "Welcome, you have no comps",
                                            style:
                                                TextStyle(color: Colors.white),
                                          ),
                                        ),
                                      ],
                                    ),
                                  ),
                                ],
                              ),
                            ],
                          );
                        }
                        return ListView.builder(
                          itemCount: snapshot.data.length,
                          itemBuilder: (BuildContext context, int index) {
                            print(index);
                            if (index == 0) {
                              return new Column(
                                children: <Widget>[
                                  Card(
                                    color: Colors.blue,
                                    child: Column(
                                      mainAxisSize: MainAxisSize.min,
                                      children: <Widget>[
                                        ListTile(
                                          title: Text(
                                            "Welcome back, these are your comps",
                                            style:
                                                TextStyle(color: Colors.white),
                                          ),
                                        ),
                                      ],
                                    ),
                                  ),
                                  SizedBox(
                                    height: 10.0,
                                  ),
                                  new CompListItem(
                                      new Comp(
                                        snapshot.data[index].left_name,
                                        snapshot.data[index].right_name,
                                        snapshot.data[index].left,
                                        snapshot.data[index].right,
                                        snapshot.data[index].left_city,
                                        snapshot.data[index].right_city,
                                        snapshot.data[index].latitude_left,
                                        snapshot.data[index].longitude_left,
                                        snapshot.data[index].latitude_right,
                                        snapshot.data[index].longitude_right,
                                        snapshot.data[index].points,
                                      ),
                                      "left")
                                ],
                              );
                            }
                            Comp tmp = new Comp(
                              snapshot.data[index].left_name,
                              snapshot.data[index].right_name,
                              snapshot.data[index].left,
                              snapshot.data[index].right,
                              snapshot.data[index].left_city,
                              snapshot.data[index].right_city,
                              snapshot.data[index].latitude_left,
                              snapshot.data[index].longitude_left,
                              snapshot.data[index].latitude_right,
                              snapshot.data[index].longitude_right,
                              snapshot.data[index].points,
                            );
                            return new CompListItem(tmp, "left");
                          },
                        );
                      } else if (snapshot.data == null) {
                        return new Container(
                          child: Text("Sorry, there seems to be a problem :("),
                        );
                      }
                    }
                  } else {
                    return CircularProgressIndicator();
                  }
                },
              ),
            ),
          ],
        ),
        floatingActionButton: Column(
          mainAxisAlignment: MainAxisAlignment.spaceEvenly,
          mainAxisSize: MainAxisSize.min,
          children: <Widget>[
            FloatingActionButton(
              heroTag: null,
              child: Icon(
                Icons.add_location,
                color: Colors.white,
              ),
              onPressed: () {
                Navigator.push(
                  context,
                  MaterialPageRoute(
                    builder: (context) => MakeComp(),
                  ),
                );
              },
              backgroundColor: Colors.blue,
            ),
            SizedBox(
              height: 10.0,
            ),
            FloatingActionButton(
              heroTag: null,
              child: Icon(Icons.compare_arrows),
              onPressed: () {
                Navigator.push(
                  context,
                  MaterialPageRoute(
                    builder: (context) => GetComps(),
                  ),
                );
              },
              backgroundColor: Colors.blue,
            ),
          ],
        ));
  }
}

实际结果:

打开应用程序-> Future Builder运行->显示数据列表->导航到另一个小部件-> Future Builder运行->单击某些按钮-> Future Builder运行

预期结果:

打开应用-> Future Builder运行->显示数据列表->导航到另一个小部件->单击某些按钮->在另一个屏幕上执行某些操作->返回主屏幕-> Future Builder运行

1 个答案:

答案 0 :(得分:0)

在我发布此问题的那一刻,我找到了答案:D

感谢RémiRousselet,他在这里回答了这个问题:

How to deal with unwanted widget build?

答案仅仅是将对Future的调用放入initState方法中,当我需要加载数据时,该方法会被精确调用。

每个人都开心飘飘!