How to push a Route from inside the body of a scaffold with a bottomnavigationbar?

598

The app bar is part of the Scaffold which will appear only on the 4 widgets In _widgetOptions. If you don't have that Scaffold on your page there is no app bar.

Wrapping your Navigator with your Scaffold (i.e. Scaffold on TOP of the Navigator) should do the trick.

Note that when you're 'returning' a Widget from a build function it becomes a child. When you are using Navigator to push a Widget it becomes a sibling and will be on top of the current screen. You can visualize this clearly in the dev tools.

EDIT: Since you're using the default MaterialApp's Navigator this won't work. You will need to create your own Navigator for this.

i.e: Remove home parameter from MaterialApp. Use builder parameter instead. And provide a Navigator widget to the builder (wrapped by your Scaffold)

Something like this:

MaterialApp(builder: (context, _) => Scaffold( ....., body: Navigator( onGenerateRoutes:...)))

Share:
598
moboldi
Author by

moboldi

Updated on December 02, 2022

Comments

  • moboldi
    moboldi over 1 year

    I have a MaterialApp in my main.dart within a Nav() Widget which contains a Scaffold with an appBar and a BottomNavigationBar. The NavigationBar has 4 BottomNavigationBarItems, but I have more Pages than 4 in my whole App. The other pages can be accessed via the first BottomNavigationBarItem 'Home'. But when I push the new NamedRoute the AppBar disapears. How can I solve this Problem?

    I've already tried using the bottomNavigationBar in my own Widget in a new File. Problem: setState() doesn't work.

    Here's some code

    main.dart:

    import 'package:flutter/material.dart';
    import 'pages/nav.dart';
    import 'route/route.dart' as route;
    
    void main() {
      runApp(MyApp());
    }
    
    class MyApp extends StatelessWidget {
      // This widget is the root of your application.
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          title: 'Lieferantenapp',
          theme: ThemeData(
            // This is the theme of your application.
            //
            // Try running your application with "flutter run". You'll see the
            // application has a blue toolbar. Then, without quitting the app, try
            // changing the primarySwatch below to Colors.green and then invoke
            // "hot reload" (press "r" in the console where you ran "flutter run",
            // or simply save your changes to "hot reload" in a Flutter IDE).
            // Notice that the counter didn't reset back to zero; the application
            // is not restarted.
            primarySwatch: Colors.red,
          ),
          home: Nav(),
          onGenerateRoute: route.controller,
          //initialRoute: route.navPage,
        );
      }
    }
    

    nav.dart

    import 'package:flutter/material.dart';
    import 'package:lieferantenapp/components/MyAppBar.dart';
    import 'package:lieferantenapp/components/MyThreeLineText.dart';
    //import 'package:lieferantenapp/components/myBottomNavigationBar.dart';
    import 'package:lieferantenapp/components/myCard.dart';
    import 'package:lieferantenapp/pages/bestellungen.dart';
    import 'package:lieferantenapp/pages/packliste.dart';
    import 'package:lieferantenapp/pages/tour.dart';
    import 'package:lieferantenapp/pages/home.dart';
    
    class Nav extends StatefulWidget {
      @override
      _NavState createState() => _NavState();
    }
    
    class _NavState extends State<Nav> {
      int _selectedIndex = 0;
      List<Widget> _widgetOptions = <Widget>[
        Home(),
        Tour(),
        Bestellungen(),
        Packliste(),
      ];
    
      void _onItemTap(int index) {
        setState(() {
          _selectedIndex = index;
        });
      }
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          //Custom App Bar without any passed data
          appBar: myAppBar(context, null, null),
          backgroundColor: Colors.white,
          bottomNavigationBar: BottomNavigationBar(
            currentIndex: _selectedIndex,
            type: BottomNavigationBarType.fixed,
            fixedColor: Colors.red,
            items: const <BottomNavigationBarItem>[
              BottomNavigationBarItem(icon: Icon(Icons.home), label: 'Home'),
              BottomNavigationBarItem(
                icon: Icon(Icons.local_shipping),
                label: 'Tour',
              ),
              BottomNavigationBarItem(
                icon: Icon(Icons.inventory_2),
                label: 'Packliste',
              ),
              BottomNavigationBarItem(
                icon: Icon(Icons.receipt_long),
                label: 'Bestellungen',
              ),
            ],
            onTap: _onItemTap,
          ),
          body: _widgetOptions.elementAt(_selectedIndex),
        );
      }
    }
    

    home.dart:

    import 'package:flutter/material.dart';
    import 'package:lieferantenapp/components/MyThreeLineText.dart';
    import 'package:lieferantenapp/components/myCard.dart';
    
    class Home extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return Column(
          children: [
            //BlackBoard Message
            //TODO get BlackBoard Message from Server
            //myThreeLineText(Context, TextTheme, OVerline, Title, Body)
            myThreeLineText(
              context,
              Theme.of(context).textTheme,
              '12.07.2021',
              'Servus und Mahlzeit!',
              "Herzlich Willkommen in der neuen Mahlzeit LieferApp mit " +
                  "optimierter Routenplanung via Google Maps.",
            ),
            Expanded(
              child: GridView.count(
                shrinkWrap: true,
                primary: false,
                padding: const EdgeInsets.all(18),
                crossAxisSpacing: 15,
                mainAxisSpacing: 15,
                crossAxisCount: 2,
                children: <Widget>[
                  myCard(
                    context,
                    Icons.map_outlined,
                    'Touren',
                    Theme.of(context).textTheme,
                    Color(0xff119052),
                  ),
                  myCard(
                    context,
                    Icons.local_shipping_outlined,
                    'Touren',
                    Theme.of(context).textTheme,
                    Color(0xffFF9444),
                  ),
                  myCard(
                    context,
                    Icons.inventory_2_outlined,
                    'Touren',
                    Theme.of(context).textTheme,
                    Color(0xff84000F),
                  ),
                  myCard(
                    context,
                    Icons.receipt_long_outlined,
                    'Touren',
                    Theme.of(context).textTheme,
                    Color(0xffCB5E5E),
                  ),
                  myCard(
                    context,
                    Icons.bookmark_border_outlined,
                    'Touren',
                    Theme.of(context).textTheme,
                    Color(0xffCC3021),
                  ),
                  myCard(
                    context,
                    Icons.settings_outlined,
                    'Touren',
                    Theme.of(context).textTheme,
                    Color(0xff57BB61),
                  ),
                ],
              ),
            ),
          ],
        );
      }
    }
    

    myCard.dart:

    import 'package:flutter/cupertino.dart';
    import 'package:flutter/material.dart';
    import 'package:lieferantenapp/route/route.dart' as route;
    
    Widget myCard(BuildContext context, IconData icon, String text, TextTheme theme,
        Color cColor) {
      return GestureDetector(
        //TODO implement ROUTE ontap start Cards
        onTap: () => {},
        child: Card(
          shape: RoundedRectangleBorder(
            borderRadius: BorderRadius.circular(30),
          ),
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              Icon(
                icon,
                color: Colors.white,
                size: 30,
              ),
              SizedBox(height: 25),
              Text(
                text,
                style: theme.bodyText1.apply(color: Colors.white),
              ),
            ],
          ),
          color: cColor,
        ),
      );
    }
    

    I am also open for Tips and Tricks to improve my code.

    EDIT - new main.dart:

    import 'package:flutter/material.dart';
    import 'package:lieferantenapp/components/MyAppBar.dart';
    
    import 'pages/nav.dart';
    import 'route/route.dart' as route;
    
    void main() {
      runApp(MyApp());
    }
    
    class MyApp extends StatelessWidget {
      // This widget is the root of your application.
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          title: 'Mahlzeit Lieferantenapp',
          theme: ThemeData(
            primarySwatch: Colors.red,
          ),
          //home: Nav(),
          //onGenerateRoute: route.controller,
          builder: (context, _) => Scaffold(
            appBar: myAppBar(context, null, null),
            body: Navigator(onGenerateRoute: route.controller),
          ),
          //initialRoute: route.navPage,
        );
      }
    }
    
  • moboldi
    moboldi almost 3 years
    Thanks for your quick answer! I am receiving following Error with the new main.dart posted above: A HeroController can not be shared by multiple Navigators. The Navigators that share the same HeroController are: The error ends after "are: " EDIT: forgot the initialRoute - fixed the error
  • moboldi
    moboldi almost 3 years
    Received another Error: The following _CompileTimeError was thrown building Builder(dirty): Unimplemented handling of missing static target The relevant error-causing widget was MaterialApp Do you know how to fix it? Or do you know another way to solve it?
  • lenz
    lenz almost 3 years
    I believe a hot restart or stop and re-run the app should fix that error.
  • lenz
    lenz almost 3 years
    And please accept and upvote my answer if it was helpful