Flutter BLoC pattern - How can I navigate to another screen after a stream event? Flutter BLoC pattern - How can I navigate to another screen after a stream event? dart dart

Flutter BLoC pattern - How can I navigate to another screen after a stream event?


Use BlockListener.

 BlocListener(  bloc: _yourBloc,  listener: (BuildContext context, YourState state) {    if(state is NavigateToSecondScreen){      Navigator.of(context).push(MaterialPageRoute(builder: (BuildContext context) {return SecondScreen();}));    }  },  child: childWidget)


The navigator is not working in blocBuilder, because in blocBuilder, you can only return a widget

But BlocListener solved it for me.

Add this code:

BlocListener(  bloc: _yourBloc,  listener: (BuildContext context, YourState state) {    if(state is NavigateToSecondScreen){      Navigator.of(context).push(MaterialPageRoute(builder: (BuildContext context) {return SecondScreen();}));    }  },  child: childWidget)


First of all: if there isn't any business logic, then there isn't any need to go to YourBloc class.

But from time to time some user's activity is required to perform some logic in Bloc class and then the Bloc class has to decide what to do next: just rebuild widgets or show dialog or even navigate to next route. In such a case, you have to send some State to UI to finish the action.

Then another problem appears: what shall I do with widgets when Bloc sends State to show a toast?

And this is the main issue with all of this story.

A lot of answers and articles recommend to use flutter_block. This library has BlocBuilder and BlocListener. With those classes you can solve some issues, but not 100% of them.

In my case I used BlocConsumer which manages BlocBuilder and BlocListener and provides a brilliant way to manage states.

From the documentation:

BlocConsumer<BlocA, BlocAState>(  listenWhen: (previous, current) {    // Return true/false to determine whether or not    // to invoke listener with state  },  listener: (context, state) {    // Do stuff here based on BlocA's state  },  buildWhen: (previous, current) {    // Return true/false to determine whether or not    // to rebuild the widget with state  },  builder: (context, state) {    // Return widget here based on BlocA's state  })

As you can see with BlocConsumer, you can filter states: you can easily define states to rebuild widgets and states to show some popups or navigate to the next screen.