Repeat my NavigationBar widget across all pages

I'd like to repeat the navigation bar across all pages, and the bottomnavigationbar works like a charm, but when I change pages using the drawer, the bottom navigationbar disappears. Followed this tutorial: https://www.youtube.com/watch?v=2emB2VFrRnA&t=1s&ab_channel=HeyFlutter%E2%80%A4com, but it only show on the main page.

This is my homepage code:

import 'package:flutter/material.dart';
import 'package:kikapp/create.dart';
import 'package:kikapp/home.dart';
import 'package:kikapp/zero.dart';

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

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
        title: 'KikApp',
        theme: ThemeData(
          colorScheme: ColorScheme.fromSeed(seedColor: Colors.grey),
          useMaterial3: true,
        ),
        debugShowCheckedModeBanner: false,
        initialRoute: 'home',
        routes: {
          'home': (context) => const Main(),
          'profile': (context) => const Create(),
          'zero': (context) => const Zero(),
        }
    );
  }
}

//Drawer
class MyDrawer extends StatelessWidget {
  const MyDrawer({super.key});

  @override
  Widget build(BuildContext context) {
    return Drawer(
        child: ListView(
          padding: EdgeInsets.zero,
          children: [
            const DrawerHeader(
              decoration: BoxDecoration(
                color: Colors.black12,
              ),
              child: Text(
                'Anarkika',
                style: TextStyle(
                  color: Colors.white,
                  fontSize: 24,
                ),
              ),
            ),
            ListTile(
              leading: const Icon(Icons.home),
              title: const Text('Home'),
              onTap: () {
                Navigator.pop(context);
                Navigator.of(context).push(
                    MaterialPageRoute(builder: (context) => const Home()));
              },
            ),
            ListTile(
              leading: const Icon(Icons.book),
              title: const Text('Zero'),
              onTap: () {
                Navigator.pop(context);
                Navigator.of(context).push(
                    MaterialPageRoute(builder: (context) => const Zero()));
              },
            ),
            ListTile(
              leading: const Icon(Icons.add),
              title: const Text('Create'),
              onTap: () {
                Navigator.pop(context);
                Navigator.of(context).push(
                    MaterialPageRoute(builder: (context) => const Create()));
              },
            ),
          ],
        ),
      );
  }
}

//Body
class Main extends StatefulWidget {
  const Main({super.key});

  @override
  State<Main> createState() => _MainState();
}

class _MainState extends State<Main> {
  int index = 0;
  final pages = [
    const Home(),
    const Zero(),
    const Create(),
  ];

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: pages[index],
      bottomNavigationBar: NavigationBar(
        height: 70,
        animationDuration: const Duration(milliseconds: 1000),
        labelBehavior: NavigationDestinationLabelBehavior.onlyShowSelected,
        backgroundColor: Colors.grey,
        indicatorColor: Colors.white,
        selectedIndex: index,
        onDestinationSelected: (index) => setState(() => this.index = index),
        destinations: const [
          NavigationDestination(icon: Icon(Icons.home_outlined), selectedIcon: Icon(Icons.home), label: 'Home',),
          NavigationDestination(icon: Icon(Icons.book_outlined), selectedIcon: Icon(Icons.book), label: 'Zero',),
          NavigationDestination(icon: Icon(Icons.add_outlined), selectedIcon: Icon(Icons.add), label: 'Create',),
        ],
      ),
    );
  }
}

class Nav extends StatefulWidget {
  const Nav({ Key? key }) : super(key: key);

  @override
  State<Nav> createState() => _NavState();
}

class _NavState extends State<Nav> {
   int index = 0;
  final pages = [
    const Home(),
    const Zero(),
    const Create(),
  ];

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      bottomNavigationBar: NavigationBar(
        animationDuration: const Duration(milliseconds: 1500),
        labelBehavior: NavigationDestinationLabelBehavior.onlyShowSelected,
        backgroundColor: Colors.grey,
        indicatorColor: Colors.white,
        selectedIndex: index,
        onDestinationSelected: (index) => setState(() => this.index = index),
        destinations: const [
          NavigationDestination(icon: Icon(Icons.home_outlined), selectedIcon: Icon(Icons.home), label: 'Home',),
          NavigationDestination(icon: Icon(Icons.book_outlined), selectedIcon: Icon(Icons.book), label: 'Zero',),
          NavigationDestination(icon: Icon(Icons.add_outlined), selectedIcon: Icon(Icons.add), label: 'Create',),
        ],
      ),
    );
  }
}

I've tried to put the widget into a separate stateful widget and copy the NavBar into the bottomnavigationbar of the page where I wanted the bar to appear. please help me.

Upvotes: -1

Views: 83

Answers (1)

Rayan Ali Siyam
Rayan Ali Siyam

Reputation: 13

What you are trying to do is not the right approach. Cause selectedIndex is responsible for showing NavigationBar's selected button and the selected Widget from the pages list in the body of Scaffold.

But what you are trying is that Navigator.of(context).push() which pushes a new Screen on top of the current Screen.

The right approach is to change the selectedIndex from Drawer's ListTile's onTap function.

Kindly check the code below. It's working!

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

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
        title: 'KikApp',
        theme: ThemeData(
          colorScheme: ColorScheme.fromSeed(seedColor: Colors.grey),
          useMaterial3: true,
        ),
        debugShowCheckedModeBanner: false,
        initialRoute: 'home',
        routes: {
          'home': (context) => const Main(),
        });
  }
}

class Main extends StatefulWidget {
  const Main({super.key});

  @override
  State<Main> createState() => _MainState();
}

class _MainState extends State<Main> {
  int selectedIndex =
      0; // Changed the variable name to `selectedIndex` from `index`.
  final pages = [
    const Home(),
    const Zero(),
    const Create(),
  ];

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text("Test App"),
      ),
      drawer: Drawer(
        child: ListView(
          padding: EdgeInsets.zero,
          children: [
            const DrawerHeader(
              decoration: BoxDecoration(
                color: Colors.black12,
              ),
              child: Text(
                'Anarkika',
                style: TextStyle(
                  color: Colors.white,
                  fontSize: 24,
                ),
              ),
            ),
            ListTile(
              leading: const Icon(Icons.home),
              title: const Text('Home'),
              onTap: () {
                setState(() {
                  selectedIndex = 0; // Index of Home() in `pages` list.
                });
                Navigator.pop(context); // To close Drawer.
              },
            ),
            ListTile(
              leading: const Icon(Icons.book),
              title: const Text('Zero'),
              onTap: () {
                setState(() {
                  selectedIndex = 1; // Index of Zero() in `pages` list.
                });
                Navigator.pop(context); // To close Drawer.
              },
            ),
            ListTile(
              leading: const Icon(Icons.add),
              title: const Text('Create'),
              onTap: () {
                setState(() {
                  selectedIndex = 2; // Index of Create() in `pages` 
                                     // list.
                });
                Navigator.pop(context); // To close Drawer.
              },
            ),
          ],
        ),
      ),
      body: pages[selectedIndex],
      bottomNavigationBar: NavigationBar(
        height: 70,
        animationDuration: const Duration(milliseconds: 1000),
        labelBehavior: 
                 NavigationDestinationLabelBehavior.onlyShowSelected,
        backgroundColor: Colors.grey,
        indicatorColor: Colors.white,
        selectedIndex: selectedIndex,
        onDestinationSelected: (index) {
          setState(() {
            selectedIndex = index;
          });
        },
        destinations: const [
          NavigationDestination(
            icon: Icon(Icons.home_outlined),
            selectedIcon: Icon(Icons.home),
            label: 'Home',
          ),
          NavigationDestination(
            icon: Icon(Icons.book_outlined),
            selectedIcon: Icon(Icons.book),
            label: 'Zero',
          ),
          NavigationDestination(
            icon: Icon(Icons.add_outlined),
            selectedIcon: Icon(Icons.add),
            label: 'Create',
          ),
        ],
      ),
    );
  }
}

// Created below Widgets to Test. You can remove these cause you have 
// Home(), Zero() and Create() Widget.
class Home extends StatelessWidget {
  const Home({super.key});

  @override
  Widget build(BuildContext context) {
    return const Center(
      child: Text("Home"),
    );
  }
}

class Zero extends StatelessWidget {
  const Zero({super.key});

  @override
  Widget build(BuildContext context) {
    return const Center(
      child: Text("Zero"),
    );
  }
}

class Create extends StatelessWidget {
  const Create({super.key});

  @override
  Widget build(BuildContext context) {
    return const Center(
      child: Text("Create"),
    );
  }
}

I hope that's the answer to your question.

Upvotes: 1

Related Questions