Is there some chance to get current context on the main.dart? I am using the sharing intent for listening applinks, and I need to redirect to specify page. But I don't know how can I use the context.
#override
Widget build(BuildContext context) {
ReceiveSharingIntent.getInitialText().then((String val){
//some logic
Navigator.pushNamed(context, ....);
});
return MaterialApp(
title: 'MyApp',
initialRoute: Routes.home,
onGenerateRoute: (RouteSettings settings) {
switch (settings.name) {
case Routes.home:
return SimplePageRoute(builder: (context) => HomeScreen());
break;
}
}
);
}
I have got this error
Unhandled Exception: Navigator operation requested with a context that
does not include a Navigator.
Ok I am understand, but how can I get the current context in this place?
Ok I fixed it with navigatorKey!!
final GlobalKey<NavigatorState> navigatorKey = new GlobalKey<NavigatorState>();
#override
Widget build(BuildContext context) {
ReceiveSharingIntent.getInitialText().then((String val){
//some logic
navigatorKey.currentState.pushNamed(Routes.myPage);
});
return MaterialApp(
title: 'MyApp',
initialRoute: Routes.home,
navigatorKey: navigatorKey,
onGenerateRoute: (RouteSettings settings) {
switch (settings.name) {
case Routes.home:
return SimplePageRoute(builder: (context) => HomeScreen());
break;
}
}
);
}
Related
I am using the builder function of my MaterialApp to wrap my routes with a widget.
But I only want to show the wrapper on specific routes.
Any idea how to achieve this?
Actually I am using GetX and GetMaterialApp, but I don't think that it makes any difference.
#override
Widget build(BuildContext context) {
return GetMaterialApp(
home: HomeScreen(),
builder: (context, child) {
//Only show GlobalPlayerWrapper on specific routes
return GlobalPlayerWrapper(child: child!);
},
title: 'Aschaffenburg',
);
}
You coul use MaterialApp's onGenerateRoute callback to generate different results depending on the route:
return MaterialApp(
onGenerateRoute: (RouteSettings settings) {
switch (settings.name) {
case'/':
return MaterialPageRoute(builder: (_) => HomeScreen());
case '/otherPage':
/* return other page route with your wrapper*/
}
},
initialRoute: MateriealPageRoute(builder:(_) => HomeScreen()),
);
I am trying to implement a simple navigation logger in my flutter app. Created
a new class extending RouteObserver:
class AuthMiddleware extends RouteObserver {
AuthMiddleware();
#override
void didPush(Route route, Route? previousRoute) {
print(
"PUSH FROM ${previousRoute.settings.name} TO ${route.settings.name} ");
super.didPush(route, previousRoute);
}
#override
void didPop(Route route, Route? previousRoute) {
print(
"POP FROM ${previousRoute.settings.name} TO ${route.settings.name}");
super.didPop(route, previousRoute);
}
}
And then assigned it to MaterialApp:
MaterialApp(
navigatorKey: rootNavigatorKey,
debugShowCheckedModeBanner: false,
themeMode: ThemeMode.light,
theme: THEME_DATA,
onGenerateRoute: (RouteSettings settings) {
String? routeName = settings.name;
Widget getPage() {
switch (routeName) {
case "/about":
return AboutPage();
default:
return HomePage();
}
}
return MaterialPageRoute(builder: (context) => getPage());
},
navigatorObservers: [AuthMiddleware()], //***Set created observer here***
),
I was expecting to see that it will print something like
PUSH FROM / TO /about
But I can only see:
PUSH FROM null TO null
What I am doing wrong?
you need to pass settings as a second parameter to MaterialPageRoute
return MaterialPageRoute(builder: (context) => getPage(), settings: settings);
Hi I am trying to add a new Provider on the root level of my App. However, the create function of the new Provider (In this case more easily represented by the Provider of type int) doens't get called as I can see in my Console.
class MyApp extends StatelessWidget {
final List<SingleChildWidget> providers = [
Provider<DynamicLinkService>(
create: (context) {
print("Dynamic Link Service Provider gets built");
return DynamicLinkService();
},
),
Provider<int>(create: (context) {
print("Int Provider gets built");
return 1;
}),
];
#override
Widget build(BuildContext context) {
return MultiProvider(
providers: providers,
builder: (ctx, _) {
return MaterialApp(
theme: themeData(context),
debugShowCheckedModeBanner: false,
title: 'Flutter Demo',
onGenerateRoute: (settings) {
return getPageRoute(settings);
},
home: StartUpView(),
navigatorKey: locator<NavigationService>().navigatorKey,
);
},
);
}
}
Console Output:
Dynamic Link Service Provider gets built
I wonder how we can call generateRoute without arguments
onGenerateRoute: RouteGenerator.generateRoute
my expectation would be:
RouteGenerator.generateRoute(settings)
Thanks,
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return StreamBuilder<int>(
stream: NumberCreator().stream,
builder: (context, snapshot) {
print('StreamBuilder: ${snapshot.connectionState}');
return MaterialApp(
title: 'Demo',
**onGenerateRoute: RouteGenerator.generateRoute,**
onGenerateInitialRoutes: (String initialRouteName) {
return [
RouteGenerator.generateRoute(
RouteSettings(name: '/', arguments: snapshot)),
];
},
);
});
}
}
class RouteGenerator {
static Route<dynamic> generateRoute(RouteSettings settings) {
final args = settings.arguments;
switch (settings.name) {
case '/':
if (args is AsyncSnapshot<int>) {
It's not really that you are calling onGenerateRoute without arguments, it is because you are passing a parameters which comply to the expected type RouteFactory defined as follow in the flutter documentation:
typedef RouteFactory = Route<dynamic>? Function(RouteSettings settings);
And your generateRoute comply to this type as it is a function which takes a RouteSettings parameter and returning an object of type Route<dynamic>.
Here is the code I've used in my projects:
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Demo',
initialRoute: /*<my_initial_route */,
onGenerateRoute: MyRouter.generateRoute,
);
}
}
class RouteGenerator {
static Route<dynamic> generateRoute(RouteSettings settings) {
switch (settings.name) {
// your cases ...
default:
return MaterialPageRoute(
builder: (_) => Scaffold(
body: Center(
child: Text('No route defined for ${settings.name}'),
),
),
);
}
}
}
I did what was suggested here for a persistent bottom bar using a custom navigator.
class _MainScreenState extends State<MainScreen> {
final _navigatorKey = GlobalKey<NavigatorState>();
// ...
#override
Widget build(BuildContext context) {
return Scaffold(
body: Navigator(
key: _navigatorKey,
initialRoute: '/',
onGenerateRoute: (RouteSettings settings) {
WidgetBuilder builder;
// Manage your route names here
switch (settings.name) {
case '/':
builder = (BuildContext context) => HomePage();
break;
case '/page1':
builder = (BuildContext context) => Page1();
break;
case '/page2':
builder = (BuildContext context) => Page2();
break;
default:
throw Exception('Invalid route: ${settings.name}');
}
// You can also return a PageRouteBuilder and
// define custom transitions between pages
return MaterialPageRoute(
builder: builder,
settings: settings,
);
},
),
bottomNavigationBar: _yourBottomNavigationBar,
);
}
}
Now, if I have child widgets on HomePage with a button that needs to navigate me to a Page2, How would I achieve that from inside HomePage - because?
some button or GestureDetector
onTap : ()=>Navigator.of(context).pushNamed('/page2')
or
onPress : ()=>Navigator.of(context).pushNamed('/page2')