Maintaining the Bottom Navigation Bar/ Menu SideBar and Navigating to New Screens in Flutter

Maintaining the Bottom Navigation Bar/ Menu SideBar and Navigating to New Screens in Flutter

Enhancing User Experience with Persistent Bottom Navigation/SideBar in Flutter Mobile and Web Apps

When building Flutter applications, especially those with complex navigation requirements, you might want to preserve a bottom navigation bar or menu sidebar (web admin) while navigating between different screens. This pattern is particularly useful for both mobile and web applications, ensuring a consistent user experience as users switch between different sections or tabs.

Solution: Using Navigator within Scaffold

To achieve this, you can use a Navigator within each section of your app while keeping the bottom navigation bar intact at the root level. This approach allows you to navigate between different screens within a section without losing the bottom navigation bar, and it's especially beneficial in Flutter web applications where maintaining a persistent navigation bar is crucial for a seamless user experience.

Here's a concise example demonstrating how to implement this pattern:

Main Screen with Bottom Navigation

import 'package:flutter/material.dart';

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

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

class _MainScreenState extends State<MainScreen> {
  int _currentIndex = 0;

  final List<Widget> _pages = [
    const HomeScreen(),
    const SearchScreen(),
    const ProfileScreen(),
  ];

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: _pages[_currentIndex],
      bottomNavigationBar: BottomNavigationBar(
        items: const <BottomNavigationBarItem>[
          BottomNavigationBarItem(
            icon: Icon(Icons.home),
            label: 'Home',
          ),
          BottomNavigationBarItem(
            icon: Icon(Icons.search),
            label: 'Search',
          ),
          BottomNavigationBarItem(
            icon: Icon(Icons.person),
            label: 'Profile',
          ),
        ],
        currentIndex: _currentIndex,
        onTap: _onItemTapped,
      ),
    );
  }
}

Home Screen with Navigator

class HomeScreen extends StatelessWidget {
  const HomeScreen({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Navigator(
      onGenerateRoute: (RouteSettings settings) {
        WidgetBuilder builder;
        switch (settings.name) {
          case '/details':
            builder = (BuildContext context) => const DetailsScreen();
            break;
          default:
            builder = (BuildContext context) => const HomePage();
        }
        return MaterialPageRoute(builder: builder, settings: settings);
      },
    );
  }
}

Home Page

class HomePage extends StatelessWidget {
  const HomePage({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Center(
      child: ElevatedButton(
        onPressed: () {
          Navigator.of(context).pushNamed('/details');
        },
        child: const Text('Go to Details Screen'),
      ),
    );
  }
}

Details Screen

class DetailsScreen extends StatelessWidget {
  const DetailsScreen({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Details Screen')),
      body: const Center(child: Text('This is the details screen')),
    );
  }
}

Search Screen

class SearchScreen extends StatelessWidget {
  const SearchScreen({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return const Center(child: Text('Search Screen'));
  }
}

Profile Screen

class ProfileScreen extends StatelessWidget {
  const ProfileScreen({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return const Center(child: Text('Profile Screen'));
  }
}

Key Points:

  • Root-Level Navigation: MainScreen contains the BottomNavigationBar and switches between pages (Home, Search, Profile) based on user interaction.

  • Section-Specific Navigation: Each section (like HomeScreen) uses its own Navigator to manage routing within that section, allowing independent navigation without affecting the bottom navigation bar.

  • Web Optimization: This pattern is particularly valuable for Flutter web applications. On the web, maintaining a persistent menu sidebar ensures that users have a consistent and intuitive navigation experience, which is crucial for usability and accessibility.

By implementing this approach, you create a fluid and user-friendly navigation experience across both mobile and web platforms, making your app more accessible and engaging.

Did you find this article valuable?

Support Flutter Aware by becoming a sponsor. Any amount is appreciated!