Screen not popping to original screen

ghz 8months ago ⋅ 67 views

I have implemented a separate screen to show the error message. In the init state of the error screen, I have implemented a timer so that it pops back to the original login screen after 3 seconds of showing the error. However, after showing the screen for 3 seconds, I get a black screen, and not the original login screen. Can someone explain why? Is there a better way to do it?

Codes:

Widget build(BuildContext context) {
    return BlocBuilder<AuthCubit, AuthState>(
      builder: (context, state) {
        if (state is AuthSuccess) {
          return buildSuccessScreen(state);
        } else if (state is AuthError) {
          return ErrorScreen(state.message);
        } else if (state is AuthPrompt) {
          return _LoginForm(buildSuccessScreen);
        } else {
          return const Scaffold(
            body: Center(child: CircularProgressIndicator()),
          );
        }
      },
    );
  }



class ErrorScreen extends StatefulWidget {
  const ErrorScreen(this.error, {super.key});

  final String error;

  @override
  State<ErrorScreen> createState() => _ErrorScreenState();
}

class _ErrorScreenState extends State<ErrorScreen> {
  @override
  void initState() {
    Timer(const Duration(seconds: 3), () {
      Navigator.pop(context);
    });

    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.grey,
      body: Center(
          child: Text(
        widget.error,
        style: const TextStyle(
          color: Colors.black,
          fontSize: 20,
        ),
      )),
    );
  }
}

Answers

The issue you're facing is likely because you're popping the error screen from the navigator stack, but you're not navigating back to the original login screen. Instead, you're just removing the error screen, leaving the navigator stack empty, resulting in a black screen.

To fix this issue, you should navigate back to the original login screen after popping the error screen. Here's how you can do it:

class _ErrorScreenState extends State<ErrorScreen> {
  @override
  void initState() {
    super.initState();
    // Start the timer after the widget has been initialized
    Timer(const Duration(seconds: 3), () {
      // Navigate back to the original login screen after 3 seconds
      Navigator.pop(context);
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.grey,
      body: Center(
        child: Text(
          widget.error,
          style: const TextStyle(
            color: Colors.black,
            fontSize: 20,
          ),
        ),
      ),
    );
  }
}

By doing this, after 3 seconds, the error screen will be popped from the navigator stack, and the original login screen will be displayed again.

Alternatively, instead of using Navigator.pop(context), if you want to navigate back to a specific screen, you can use Navigator.pushReplacement to replace the current screen with the login screen. For example:

Timer(const Duration(seconds: 3), () {
  Navigator.pushReplacement(
    context,
    MaterialPageRoute(builder: (context) => LoginScreen()),
  );
});

Replace LoginScreen() with the appropriate widget for your login screen.