Home > database >  My FutureBuilder on my home screen keeps reloading (but ONLY when on other screens)?
My FutureBuilder on my home screen keeps reloading (but ONLY when on other screens)?

Time:10-29

I am encountering a very bizarre problem with my FutureBuilder on my home screen that only shows up when I've navigated to other pages and then it keeps reloading (I've verified by putting breakpoints on my home screen).

I'm fairly certain this is not how FutureBuilders are supposed to act, or even why it's reloading in a loop only away from my home screen?

CONOPS:

  1. I load my app
  2. the FutureBuilder on the home screen works as expected. It receives its futures, builds the app, and that's that
  3. I navigate to another screen
  4. the FutureBuilder on my home screen suddenly starts firing again and won't stop

My home screen code, which is a Stateful widget:

  @override
  Widget build(BuildContext context) {
    generateLayout(); // Assigns padding/spacing based on screen size
    return MaterialApp(
      title: 'Home Screen',
      // This builder is here for routes needing an up-the-tree context
      home: Builder(builder: (context) { 
        Future.delayed(Duration.zero, () {
          // Shows disclosure on location usage
          return showLocationDisclosureDetermination(context); 
        });
        return Scaffold(
          appBar: AppBar(
            title: startScreenTitle('Location Alerts'),
          ),
          body: FutureBuilder(
              future: initFunctions(),
              builder: (BuildContext context, AsyncSnapshot<bool> snapshot) {
                if (snapshot.hasData) {
                  return startScreenBody(context);
                } else {
                  return const Center(
                      child: CircularProgressIndicator(
                    color: Color(s_darkSalmon),
                  ));
                }
              }),
        );
      }),
    );
  }

My initFunctions() code:

  Future<bool> initFunctions() async {
    await sharedPreferencesLookUp();     // Getting Shared Preferences vars
    await databaseLookUp();              // Doing a Firestore query
    await locationServicesLookUp();      // Getting location services info
    return true;
  }

And lastly, how I navigate away from the home screen:

return ElevatedButton(
    onPressed: () async {
      Navigator.push(
        context,
        MaterialPageRoute(builder: (context) => const SpecificScreen()),
      );
    },
    child: Text('Go Right'));

Any ideas would be helpful, thank you!!

CodePudding user response:

You can try using FutureBuilder connectionState:

 FutureBuilder(
    future: initFunctions(),
    builder: (BuildContext context, AsyncSnapshot<bool> snapshot) {
      switch (snapshot.connectionState) {
        case ConnectionState.done:
          if (snapshot.hasData) {
            return startScreenBody(context);
          } else {
            return const Center(child: Text("no data"));
          }
        case ConnectionState.waiting:
          return const Center(
              child: CircularProgressIndicator(
            color: Color(s_darkSalmon),
          ));

        default:
          return const Center(
              child: CircularProgressIndicator(
            color: Color(s_darkSalmon),
          ));
      }
    });

CodePudding user response:

NOTE THIS IS A HACK/WORKAROUND, I AM OP

For anyone who comes across this in the future, I found a hack/workaround that hopefully can help you. Note this does not solve the FutureBuilder repeatedly firing, but does hide the behavior from the user.

I added a bool on my home screen called _on_this_page to let my FutureBuilder function initFunctions() know when to actually execute. Here's how I did it with the Navigator to keep things somewhat clean.

bool _on_this_page = true; // Instantiation in Stateful widget before build()

return ElevatedButton(
    onPressed: () async {
      _on_this_page = false; // for when you leave
      Navigator.push(
        context,
        MaterialPageRoute(builder: (context) => const SpecificScreen()),
      ).then((value) => setState(() {
            _on_this_page = true; // for when you come back
            ;
          }));
    },
    child: Text('Go Right'));
  • Related