Reputation: 229
So, I'm using the auto_route package for navigation in my app and flutter_bloc
for state management. When I was using the old Navigator, I could just wrap a route with a BlocProvider. For example:
class Router {
static Route<dynamic> generateRoute(RouteSettings settings) {
switch (settings.name) {
case '/':
return MaterialPageRoute(
builder: (_) => BlocProvider( // wrapped Home with BlocProvider
create: (context) => SubjectBloc(),
child: Home(),
),
);
case '/feed':
return MaterialPageRoute(builder: (_) => Feed());
}
}
}
Now, auto_route uses annotations to generate a routing file. How would I go around providing provider context to the route?
Upvotes: 7
Views: 13462
Reputation: 41
You can also use a custom route builder.
Route<T> myCustomRouteBuilder<T>(BuildContext context, Widget child, CustomPage<T> page){
return PageRouteBuilder(
fullscreenDialog: page.fullscreenDialog,
// this is important
settings: page,
pageBuilder: (,__,___) => BlocProvider( // wrapped page with BlocProvider
create: (context) => SubjectBloc(),
child: child,
),
);
}
@AutoRoute(
replaceInRouteName: 'Page,Route',
routes: [
// ...
CustomRoute(
path: '/'
page: FeedPage
// ...
customRouteBuilder: myCustomRouteBuilder,
// ...
),
// ...
]
)
where FeedPage
is your the Feed
widget. Each page in auto_route
should have a pre-defined suffix in its name as you probably already know.
Upvotes: 2
Reputation: 3945
The answer depends on how your routes are constructed, I'll show you how I achieve this.
For nested routes (When you provide children to your routes), you can use a wrapper. You can wrap your bloc provider(s) around the child and it will provide the bloc to all children screens.
/// routes
AutoRoute(
page: SupportWrapper,
name: 'SupportRouter',
path: 'support',
children: [
AutoRoute(
page: HelpSupportScreen,
path: '',
),
AutoRoute(
page: MessageUsScreen,
path: 'issue',
),
],
),
/// build method of [support_wrapper.dart]
@override
Widget build(BuildContext context) {
return MultiBlocProvider(
providers: [
BlocProvider(
create: (context) => _supportCubit,
),
],
child: const AutoRouter(),
);
}
If you are not using a wrapper widget, e.g. its a single screen with no children routes, I would create a separate widget to wrap the BlocProvider
around the screen.
class SupportScreen extends StatelessWidget {
const SupportScreen({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return BlocProvider(
create: (context) => _supportCubit
child: const _SupportScreen(),
);
}
}
class _SupportScreen extends StatelessWidget {
const _SupportScreen({Key? key}) : super(key: key);
// rest of your screens code...
Upvotes: 7
Reputation: 229
We have our page widget (state/less/ful) implement AutoRouteWrapper
class HomePage extends StatelessWidget implements AutoRouteWrapper{
.....
@override
Widget wrappedRoute(context){
return BlocProvider(
create: (context) => HomeBloc(),
child: this, // this as the child Important!
);
}
}
Upvotes: 8