0

我尝试在 Flutter 中使用 FutureBuilder 来等待我的 initState 完成,然后为应用程序构建 UI。但是当应用程序运行时,每次我按下另一个按钮时屏幕都会不断重建(按钮的作用完全不同)。

Future loadUser() async {
    String jsonString = await storage.read(key: "jwt");
    final jsonResponse = json.decode(jsonString);
    loggedUser = new LoggedUser.fromJson(jsonResponse);
    print(loggedUser.token);
    getProfile();
    getJourneyByUserId()
        .then((receivedList){
      addRanges(receivedList);});
    }

Future<List<Journey>>getJourneyByUserId() async {
    var res = await http.get(
      Uri.parse("$baseUrl/journeys/userid=${loggedUser.user.userId}"),
      headers: {
        'Content_Type': 'application/json; charset=UTF-8',
        'Authorization': 'Bearer ${loggedUser.token}',
      },
    );
    if (res.statusCode == 200) {
      print("Get journeys successfully");
    }
    var data = jsonDecode(res.body);
    List idList = [];
    for (var i in data) {
      idList.add(i["journeyId"]);
    }
    for (var i in idList) {
      var res = await http.get(
        Uri.parse("$baseUrl/journeys/$i"),
      );
      var data = jsonDecode(res.body);
      Journey userJourney = new Journey.fromJson(data);
      setState(() {
        journeyList.add(userJourney);
      });
    }
    print("Journey ${journeyList.length}");
    return journeyList;
  }

addRanges(journeyList){
    setState(() {
      rangeList=[];
    });
      if (journeyList.isNotEmpty) {
        for (var i in journeyList) {
          DateTime startDate =
          DateTime(i.startDate.year, i.startDate.month, i.startDate.day);
          DateTime endDate =
          DateTime(i.endDate.year, i.endDate.month, i.endDate.day);
          setState(() {
            rangeList.add(PickerDateRange(startDate, endDate));
          });
        }
      }
      print("Range ${rangeList.length}");
      return rangeList;
  }

returnRange() {
    List<PickerDateRange> list = [];
    for(int i =0; i<rangeList.length;i++){
      list.add(rangeList[i]);
    }
    return list;
  }

Future functionForBuilder() async {
    return await returnRange();
  }

//initState function
  @override
  void initState() {
    super.initState();
    loadUser();
    functionForBuilder();
  }

//build the UI
Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: Text("$_name's Profile",style: TextStyle(color: kColorPalette4),),
          centerTitle: true,
        ),
        body: Container(
          child: FutureBuilder(
            future: functionForBuilder(),
            builder: (BuildContext context,AsyncSnapshot snapshot){
            //here I set the condition for each case of snapshot
}

我已经阅读了一些文档,说我应该在 initState 时将 functionForBuilder() 分配给 Future 变量,然后在 FutureBuilder 的未来子代中使用它。例子:

Future _future;

//initState function
  @override
  void initState() {
    super.initState();
    loadUser();
    _future=functionForBuilder();
  }

// then with the FutureBuilder
future: _future

通过这种方式,屏幕不再重建,但我的函数 returnRange() 似乎没有像我的 expextation 一样运行(我在 build() 函数中调用了 returnRange() 一次)。

提前感谢您的回答!

4

3 回答 3

0

如果您使用 FutureBuilder,它会一次又一次地重建项目。

尝试两种方法:

  1. 不要使用`future: functionForBuilder(),注释掉。
  2. 移除 FutureBuilder(),只需使用 Container()。

让我知道任何问题?

于 2021-08-12T05:28:08.173 回答
0

每当您再次分配给_future变量时,您必须在setState块内执行此操作,否则小部件将不会随着新的未来重建。

例如:

void updateData() {
  setState(() {
      _future = functionForBuilder();
  });
}
于 2021-08-12T04:24:07.253 回答
0

代码:

如示例所示,在 initstate 方法中调用您的未来,而不是在构建中。

class MyPage extends StatefulWidget { @override State<MyPage> createState() => _MyPageState(); } class _MyPageState extends State<MyPage> { // Declare a variable. late final Future<int> _future; @override void initState() { super.initState(); _future = _calculate(); // Assign your Future to it. } // This is your actual Future. Future<int> _calculate() => Future.delayed(Duration(seconds: 3), () => 42); @override Widget build(BuildContext context) { return Scaffold( body: FutureBuilder<int>( future: _future, // Use your variable here (not the actual Future) builder: (_, snapshot) { if (snapshot.hasData) return Text('Value = ${snapshot.data!}'); return Text('Loading...'); }, ), ); } }

于 2021-08-12T06:37:51.033 回答