Search code examples
flutterblocflutter-bloc

Child Screen stays mounted after Parent is removed from screen. Flutter Bloc


Below is the code that checks on app start whether to show the AuthorizationScreen or the HomeScreen (called NavigationController in my code).

When the state is AuthenticationUnAuthenticated, the AuthorizaionScreen is displayed. The AuthoriazationScreen has 2 further screens for SignUp and Login.

Widget build(BuildContext context) {
    return BlocBuilder<AuthenticationBloc, AuthenticationState>(
      bloc: BlocProvider.of<AuthenticationBloc>(context),
      builder: (context, state) {

        // * as long as the state is 'Authentication-Un-Initialized',
        // * the SplashScreen will remain visible
        if (state is! AuthenticationUninitialized) {
          FlutterNativeSplash.remove();
        }

        if (state is AuthenticationUnAuthenticated) {
          return AuthorizationScreen(userRepository: userRepository);
        }

        if (state is AuthenticationAuthenticated) {
          return const NavigationController();
        }

        if (state is AuthenticationLoading) {
          return const LoadingScreen();
        }

        return const Center(
          child: Text('Auth State Error'),
        );
      },
    );
  }

The AuthorizationScreen has a button that pushes LoginScreen to stack. CustomPageRoute is to add transition from left to right.

PrimaryButton(
  onPressed: () {
    Navigator.of(context).push(
      CustomPageRoute(
        child: BlocProvider.value(
          value: _loginBloc,
          child: const SignInScreen(),
        ),
      ),
    );
  },
  child: const Text('Sign In'),
)

The Problem:

From the AuthorizationScreen when i open the LoginScreen and enter details and login the user. The state changes to AuthenticationAuthenticated, and the NavigationController is mounted.

But still the LoginScreen is the visible screen. Only when i press the back button the LoginScreen pops and the NavigationController becomes visible.

Shouldn't the LoginScreen be removed when the state was changed and the NavigationController should be the visible screen.


Solution

  • Replying late but I found the solution. If you go with the above approach, then in the SignInScreen() you need to check the state of AuthenticationBloc, if it changes to Authenticated, then pop the SignInScreen().