I'm trying to embed my whole App into an AppBar and a Footer. So I tried giving a custom Builder to my MaterialApp which look like this (I replaced the footer and the app bar by a button for clarity)
import 'package:epicture/scenes/Landing.dart';
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'My App',
initialRoute: '/',
builder: (context, child) => Container(
child: FlatButton(
child: Text('Click me'),
onPressed: () => Navigator.of(context).pushNamed('/app'),
)),
// In my current code
builder: (context, child) => Embedder(child),
routes: <String, WidgetBuilder>{
'/': (context) => Landing(),
'/app': (context) => Text('My App !'),
},
);
}
}
But on press of the 'Click me' button, an error is raised saying that the context doesn't have a Navigator
the context used to push or pop routes from the Navigator must be that of a widget that is a descendant of a Navigator widget
But actually, the button is a footer that can be clicked to change page from every page.
I would like to know how to have access to the navigator from the custom builder and if I simply head toward the wrong way for having the same pattern in every page of my application (Footer + header)
MaterialApp is a widget that introduces a number of widgets Navigator, Theme that are required to build a material design app. Scaffold Widget is used under MaterialApp, it gives you many basic functionalities, like AppBar, BottomNavigationBar, Drawer, FloatingActionButton, etc.
In Flutter these elements are called routes and they're managed by a Navigator widget. The navigator manages a stack of Route objects and provides two ways for managing the stack, the declarative API Navigator. pages or imperative API Navigator. push and Navigator.
The Navigator. push() method is used to navigate/switch to a new route/page/screen. Here, the push() method adds a page/route on the stack and then manage it by using the Navigator. Again we use MaterialPageRoute class that allows transition between the routes using a platform-specific animation.
You cannot access Navigator
with context
from inside the builder
as any widget returned by this builder
will be parent for the navigator.
So, what do I do? Can I access navigator here, how?
Yeah! You can, create a GlobalKey
and pass it to your MaterialApp
. Then use that key to access Navigator
inside your builder
.
Example:
import 'package:epicture/scenes/Landing.dart';
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
final GlobalKey<NavigatorState> _navigator = GlobalKey<NavigatorState>();
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'My App',
initialRoute: '/',
navigatorKey: _navigator,
builder: (context, child) {
return Container(
child: FlatButton(
child: Text('Click me'),
onPressed: () => _navigator.currentState.pushNamed('/app'),
),
);
},
routes: <String, WidgetBuilder>{
'/': (context) => Landing(),
'/app': (context) => Text('My App !'),
},
);
}
}
Hope that helps!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With