Notbad
Notbad

Reputation: 6296

Best way to move to a new screen when future ends

I have a splash screen that gets data from an api. I want this screen to be active (It contains a cirucular progress widget) while the data is being fetched, but as soon as it is fetched I must push a new route to go to next screen.

I have been playing a bit with futurebuilder but this seems not to be the correct widget becasue I don't want to build anything (at least in this screen) when the data is fetched. I just want to keep it as a global state data and move forward.

What's the best way to accomplish this in flutter?

This is what I have right now:

class SplashScreen extends StatelessWidget {

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: Text("Guid Template test"),
        ),
        body: Container(
          child: Center(
              child: FutureBuilder(
                future: getMenuConfiguration(),
                builder: (builderContext, snapShot) {
                  //Here I would like to move to next screen, but this seems off because this is a builder method. Doesn't seem best option just a hack.
                  return Container();
                },

              )
          ),
        ));
  }

  Future<String> getMenuConfiguration() async
  {
    String url = "https://...";
    http.Response response = await http.get(url);

    if (response.statusCode == 200) {
      var m = json.decode(response.body);
      MenuModel.fromJson(m);
    }
    else {
      throw Exception('Failed to load post');
    }
  }

}

Upvotes: 1

Views: 1630

Answers (2)

RegularGuy
RegularGuy

Reputation: 3676

Indeed , to keep it simple you just use a stateful widget [futurebuilder it's a statefulwidget].

I have a loading screen that looks like this

class LoadingScreen extends StatefulWidget {
  @override
  _LoadingScreenState createState() => _LoadingScreenState();
}

class _LoadingScreenState extends State<LoadingScreen> {
   @override
  void initState() {
    super.initState();
    Future.delayed(Duration.zero, () {
      checkCredentials(context);


  }

  checkCredentials(context) async {
  var test = await yourFunction();
  Navigator.of(context).pushReplacementNamed('/Page.Tabs');
  }
  @override
  Widget build(BuildContext context) {
    return SizedBox();
  }
}

I use Future.delayed(Duration.zero because for some reason it crashes if checkCredentials is sync ;_; , oh , and initState has access to the context :D

Upvotes: 1

Mangaldeep Pannu
Mangaldeep Pannu

Reputation: 3987

Try this

First make your class StateFulWidget

@override
void initState() {
  onStart();
}

void onStart() async {
  await getMenuConfiguration();  //load your data here
  Navigator.push();  //push to next screen
}

Upvotes: 3

Related Questions