0
votes

I am fairly new to flutter, so I'm sorry if this is a simple question. Anyways, I have a screen on my app which is a stateful widget. To my understanding, a stateful widget immediately changes state when the setState() function is called. In doing so, the build() function is immediately called.

However, when my code runs the function below (called onPressed for a button) it runs the entire function and then changes the state.

  void buttonPressed() {
    if (formKey.currentState.validate()) {
      setState(() {
        isLoading = true;
      });

      sleep(Duration(seconds: 3));
      Navigator.pushReplacement(context, MaterialPageRoute(
        builder: (context) => NextScreen(),
      ));
    }
  }

What I am trying to do is implement a traditional loading icon that spins for 3 seconds (in this case) before moving on to the next screen. However, what actually happens when I run this is that the app completely halts for 3 seconds, shows the loading icon for a fraction of a second, and then moves to NextScreen().

I tried working around this (in case it was an issue with the call stack) by putting the sleep() and Navigator.pushReplacement() lines in a separate method. This did not work either.

Any ideas why this is happening and/or how I could fix it. Any suggestions help, thanks!

2

2 Answers

0
votes

Try wrapping your loading icon inside a timer, so i did some thing similar for a project i was working on which was showing a count down.

 StartTimer() {
    const oneSec = const Duration(seconds: 1);
    _timer = new Timer.periodic(
      oneSec,
      (Timer timer) => setState(
        () {
          if (_start < 1) {
            alarmState = StateOfAlarm.Listening;
            buttonText = "Movement alarm active";
            _lockPhone();
            _startListening();

            timer.cancel();
          } else {
            _start = _start - 1;
            buttonText = _start.toString();
          }
        },
      ),
    );
  } 

   
0
votes

What I am trying to do is implement a traditional loading icon that spins for 3 seconds (in this case) before moving on to the next screen.

That is not what a traditional loading icon does. A loading icon is displayed as a placeholder WHILE you are waiting for something to complete, not displayed for a while before you do/start something.

I assume you want to display the loading indicator while the next page loads. In that case you need to control the indicator ON THE NEXT PAGE.

So, change your function to

void buttonPressed() {
  if (formKey.currentState.validate()) {
    Navigator.pushReplacement(context, MaterialPageRoute(
      builder: (context) => NextScreen(),
    ));
  }
}

Then, on the NextScreen

declare, and initialise isLoading to true

have the process which you need to wait for set isLoading to false when it completes

then, in the widget build, use a ternary condition to display EITHER the progress indicator OR the real widget