1

问题我的 FutureBuilder 在应用程序首次运行时等待,但在应用程序更新时不等待。

当我的应用程序完成加载并更改为不同的 ToggleButton 时,FutureBuilder立即开始重新运行,而不是等待getData()并且它在getData()完成之前完全完成,然后当getData()最终完成时,FutureBuilder再次运行。

应用程序首次运行时不会发生此问题。当应用程序首次运行时,FutureBuilder会等待getData()完成后再运行。

我需要FutureBuilder等待getData()在按下不同按钮时完成,就像应用程序首次启动时一样。

注意:为了可读性,我尽可能多地删除了不必要的代码。如果有帮助,我可以添加更多代码。

代码:

class PriceScreenState extends State<PriceScreen> {
  String selectedCurrency = 'USD';
  String selectedGraphType = "1D";
      var isSelectedGraph = <bool>[true, false, false, false, false, false];

getData() async {
    isWaiting = true;
    try {
      Map graphData = await GraphData().getGraphData(
          selectedCurrency: selectedCurrency,
          selectedGraphType: selectedGraphType);
      isWaiting = false;
      setState(() {
        graphValues = graphData;
      });
    } catch (e) {
      print(e);
    }
  }

 @override
  void initState() {
    super.initState();
    futureData = getData();
  }

@override
  Widget build(BuildContext context) {
...(other code)...
ToggleButtons( ****************TOGGLEBUTTONS***********
                children: <Widget>[
                  Padding(
                    padding: EdgeInsets.symmetric(horizontal: 16.0),
                    child: Text('1D'),
                  ),
                 ...(more Buttons)...
                ],
                onPressed: (int index) {
                  setState(() {
                    for (int buttonIndex = 0;
                        buttonIndex < isSelectedGraph.length;
                        buttonIndex++) {
                      if (buttonIndex == index) {
                        isSelectedGraph[buttonIndex] = true;
                        selectedGraphType = graphType[buttonIndex];
                      } else {
                        isSelectedGraph[buttonIndex] = false;
                      }
                    }
                  });
                  getData();
                },
                isSelected: isSelectedGraph,
              ),
              Expanded(
                child: FutureBuilder( *************FUTUREBUILDER*********
                    future: futureData,
                    builder: (context, snapshot) {
                      if (graphValues.isEmpty) {
                        return new Container();
                      } else {
                        return Graph(graphValues);
                      }
                    }),
              )
4

1 回答 1

1

当您使用 aFutureBuilder时,您不再需要调用setState。这是您的代码可能的返工:

Future<Map> futureData;

Future<Map> getData() async {
   try {
      Map graphData = await GraphData().getGraphData(
         selectedCurrency: selectedCurrency,
         selectedGraphType: selectedGraphType,
      );
      return graphData;
   } catch (e) {
      throw Exception(e);
   }
}

@override
void initState() {
   super.initState();
   futureData = getData();
}

@override
Widget build(BuildContext context) {
   // Only coding the FutureBuilder for the example
   return FutureBuilder<Map>(
      future: futureData,
      builder: (context, snapshot) {
         // Future is still loading
         if (!snapshot.hasData)
            return CircularProgressIndicator();
         else if (snapshot.data.isEmpty)
            return Container();
         else
            return Graph(snapshot.data);
      },
   );
}

为了让您FutureBuilder正常工作,您需要在您的变量中返回一个值getData并使用该snapshot变量。

于 2020-10-28T13:05:23.527 回答