Mohammad Fatoni
Mohammad Fatoni

Reputation: 539

How to hide navigation bar after moving to another page (flutter)?

In the homepage i am calling widget to my body main.dart base on navigation bar option, in the homepage it has a list of images, if i click one of the images, it shows me the detail. the problem is the navigation bar in the detail page still show. How to hide the navigation bar?

Main.dart

class MyApp extends StatefulWidget {
  @override
  _NavState createState() => _NavState();
}

class _NavState extends State {
  int _selectedIndex = 0;

  final _widgetOptions = [
    Breakfast(),
    Desert(),
  ];

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: _widgetOptions.elementAt(_selectedIndex),
      bottomNavigationBar: Container(
        color: Colors.grey[100],
        child: DefaultTabController(
          length: 2,
          child: TabBar(
            indicatorColor: Colors.grey,
            labelColor: Colors.blueAccent,
            unselectedLabelColor: Colors.grey,
            onTap: _onItemTapped,
            tabs: [
              Tab(
                text: 'Breakfast',
              ),
              Tab(
                text: 'Dessert',
              ),
            ],
          ),
        ),
      ),
    );
  }

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

One of widget that i call to my homepage

class Breakfast extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final title = "Fatoni's Resto Menu";
    return MaterialApp(
      title: title,
      home: Scaffold(
        appBar: AppBar(
          title: Text(title),
          actions: <Widget>[
            IconButton(
              icon: Icon(Icons.settings),
              onPressed: () {},
            )
          ],
        ),
        body: GridView.builder(
          itemCount: DataBreakfast.listViewData.length,
          gridDelegate:
              SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 2),
          itemBuilder: (context, index) {
            return Column(
              children: <Widget>[
                Expanded(
                  child: Card(
                    margin: EdgeInsets.all(10.0),
                    child: InkWell(
                      onTap: () {
                        Navigator.push(
                          context,
                          MaterialPageRoute(
                            builder: (context) {
                              return DetailScreen(
                                  name: DataBreakfast.listViewData[index],
                                  image: DataBreakfast.listViewDataImage[index],
                                  info: DataBreakfast.listViewDataInfo[index],
                                  index: index);
                            },
                          ),
                        );
                      },
                    ),
                  ),
                )
              ],
            );
          },
        ),
      ),
    );
  }
}

Upvotes: 2

Views: 7949

Answers (3)

Ramin.bagherian
Ramin.bagherian

Reputation: 71

you can use provider as well ! i have use this solution, i hope this can help to anybody else

in main method pass ChangeNotifierProvider as runApp() parameters:

void main() {
  runApp(
    providers: [
      ChangeNotifierProvider(create: (_) => BottomModel()),
      // add any other providers model
      ],
      child: MyApp(),
     ),
   );
  }

after then in build method create Consumer type of BottomModel and builder method to get model values and return BottonNavigationBar like below :

      @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      title: 'Material App',
      home: Scaffold(
        backgroundColor: backgroundColor,
        bottomNavigationBar: Consumer<BottomModel>(
          builder: (context, height, child) {
            return Wrap(children: [
              Container(
                height: height.getHeight(),
                child: BottomNavigationBar(
                  currentIndex: _curentState,
                  onTap: (index) {
                    setState(() => _curentState = index);
                  },
                  items: [
                    BottomNavigationBarItem(
                    ......

NOTE: as you know we con't set height straight for bottom navigation bar! so we have to add it in to a Container and set height to that

and BottomModel class should be like this :

class BottomModel extends ChangeNotifier {
  double _height = 60;
  double getHeight() => _height;

  void updateHeight(double height) {
    _height = height;
    notifyListeners();
  }
}

now you can change bottom navigation height with this method wherever you would like

Provider.of<BottomModel>(context , listen : false).updateHeight(height)

remember you should not forget set listen : false in provider method !

and in the end i am sorry for my bad english

Upvotes: 0

Logemann
Logemann

Reputation: 2953

You don’t make a page transition in your tap action. If you just change the body of your main screen, the other parts are of course still visible. In fact you shouldn’t put a whole new Scaffold into another scaffolds body. And for sure not a MaterialApp Widget as someone else already noted.

You need to correct a few things:

  • use MaterialApp only in the build() method of _NavState above Scaffold

  • remove the MaterialApp and the Scaffold widget from the breakfast class

  • use a container before your Gridview builder in your breakfast class. Remember, when replacing a Scaffolds body, you only want to have lower level widgets like Containers in there, not whole building blocks like other Scaffolds.

  • make bottomNavigationBar visible depending on the state of your _NavState

like:

bottomNavigationBar: _selectedIndex == 0 ? 
   Container(
    color: Colors.grey[100],
    child: DefaultTabController(...) 
   : null

Upvotes: 3

Pablo Barrera
Pablo Barrera

Reputation: 10963

The _widgetOptions, like Breakfast, shouldn't wrap the Scaffold with MaterialApp.

MaterialApp should be near the root of your app.

Upvotes: 5

Related Questions