Search code examples
flutterdartblocprovider

Convenient way to share BLoC between multiple screen


I am looking for the most convenient way to share bloc in different screens/pages without providing at top of the material app. For example I have a Customer bloc, which is required in CustomerListScreen and CustomerDetailsScreen. The bloc is created in CustomerListScreen and passed it to the CustomerDetailsScreen while navigating.

Navigator.context, MaterialPageRoute(builder: (context) => CustomerDetailsScreen(context.read<CustomerBloc>())));

This is the procedure I am following right now. Looking for any better approach available out there..


Solution

  • You could make the Bloc a required field of the page, something like this:

    class CustomerDetailsScreen extends StatelessWidget { 
      CustomerDetailsScreen(this.mybloc);
    
      final Bloc mybloc;
    
      @override
      Widget build(BuildContext context) {
        return  BlocProvider.value(
          value: mybloc,
          child: Text('Body...'),
        );
      }
    }
    

    Now, even if you use a package like AutoRoute you will still be able to provide the bloc to the page route.

    Even though I don't like this solution because what if you navigated through a url then you can't pass the bloc to it, for this i recommend to use nested navigation read this

    it will look something like this if you use AutoRoute

    @MaterialAutoRouter(              
      replaceInRouteName: 'Page,Route',              
      routes: <AutoRoute>[              
        AutoRoute(                            
          page: BlocProviderPage,              
          children: [              
            AutoRoute(page: CustomerListScreen),              
            AutoRoute(page: CustomerDetailsScreen),          
          ],              
        ),             
      ],              
    )              
    class $AppRouter {} 
    
    class BlocProviderPage extends StatelessWidget {          
      @override          
      Widget build(BuildContext context) {          
        return BlocProvider(
                create: (context) => MyBloc(),       
                child: AutoRouter(),          
        );          
      }          
    }  
    

    This way both pages will have access to the bloc and you cant navigate to them without a BlocProviderPage being a parent of them