1
votes

I have a flutter app with bottomNavigationBar, appBar, etc also I need to do a navigation. Is it possible to do something like layouts in web dev instead of using Scaffold on each page? 'cause I wouldn't like to draw bottom navigation on each screen.

This way doesn't work

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: Scaffold(
        appBar: AppBar(
          title: Text('f'),
        ),
        bottomNavigationBar: BottomBar(),
        body: Com(),
      ),
    );

class Com extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return RaisedButton(
      child: Text('go'),
      onPressed: () => {
        Navigator.pushReplacement(
          context,
          MaterialPageRoute(
              builder: (context) => Cam()),
        )
      },
    );
  }
}

class Cam extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return Text('Cam');
  }

}


It renders a button in good way, but after I use navigation, layout crashes and I get only text on black screen P.S. BottomBar is just my custom BottomNavigationBar

1
I updated my answer based on the new information that you provided. - William Terrill

1 Answers

1
votes

I created a dartpad to show how this would work dynamically: https://dartpad.dev/4125ebd6684e4cb2c69c5ec4560caab3

The way to approach this would be to use only one scaffold high up in the widget tree, and just change the widgets below, specifically in the Scaffold body: parameter. Note: you cannot use the Navigation widget with this method because it would pop off the Scaffold.

Just in case the dartpad doesn't work, you can see the code here.

import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(home: MyPages());
  }
}

class MyPages extends StatefulWidget {
  MyPages({Key key}) : super(key: key);

  @override
  MyPagesState createState() => MyPagesState();
}

class MyPagesState extends State<MyPages> {
  int _selectedIndex = 0;
  List<Widget> _widgetOptions = <Widget>[
    Container(
      color: Colors.green,
      child: Center(child: Text("put your pages here")),
      constraints: BoxConstraints.expand(),
    ),
        Container(
      color: Colors.green,
      child: Center(child: Text("you just have to build them and...")),
      constraints: BoxConstraints.expand(),
    ),
        Container(
      color: Colors.green,
      child: Center(child: Text("put them in the _widgetOption list")),
      constraints: BoxConstraints.expand(),
    )
  ];

  void _onItemTapped(int index) {
    setState(() {
      _selectedIndex = index;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('BottomNavigationBar Sample'),
      ),
      body: Center(
        child: _widgetOptions.elementAt(_selectedIndex),
      ),
      bottomNavigationBar: BottomNavigationBar(
        items: const <BottomNavigationBarItem>[
          BottomNavigationBarItem(
            icon: Icon(Icons.home),
            title: Text('Home'),
          ),
          BottomNavigationBarItem(
            icon: Icon(Icons.business),
            title: Text('Business'),
          ),
          BottomNavigationBarItem(
            icon: Icon(Icons.school),
            title: Text('School'),
          ),
        ],
        currentIndex: _selectedIndex,
        selectedItemColor: Colors.amber[800],
        onTap: _onItemTapped,
      ),
    );
  }
}

As you can see, there is only one Scaffold and bottomNavigationBar, but three pages that can be displayed. Hitting the nav buttons just updates the index to _widgetOptions. Therefore, to use this method, you just have to populate _widgetOptions with the pages that you want to show, either dynamically or statically: