Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Navigator from MaterialApp builder

Tags:

flutter

dart

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)

like image 792
Yooooomi Avatar asked Oct 09 '19 16:10

Yooooomi


People also ask

What is the difference between scaffold and MaterialApp?

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.

What is navigator in Flutter how is it used?

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.

How does Navigator push work?

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.


1 Answers

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!

like image 109
Hemanth Raj Avatar answered Nov 04 '22 07:11

Hemanth Raj