free geoip
36

Nested Navigation in Flutter Using Dart

Creating complex mobile applications in Flutter often involves managing navigation between multiple screens. In such scenarios, nested navigation in Flutter…

Creating complex mobile applications in Flutter often involves managing navigation between multiple screens. In such scenarios, nested navigation in Flutter using Dart becomes essential. This technique is useful for apps with tabs, side drawers, or bottom navigation bars, where each section requires its own navigation stack.

Nested navigation in Flutter

In this guide, you’ll learn how to implement nested navigation in Flutter using Dart programming language inside Android Studio. We’ll build a simple app with a bottom navigation bar, and each tab will maintain its own navigation history.

Step-by-Step Guide with Source Code

1. main.dart
import 'package:flutter/material.dart';
import 'navigation_home.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Nested Navigation Demo',
      home: NavigationHome(),
    );
  }
}

2. navigation_home.dart

import 'package:flutter/material.dart';
import 'screens/home_screen.dart';
import 'screens/profile_screen.dart';

class NavigationHome extends StatefulWidget {
  @override
  _NavigationHomeState createState() => _NavigationHomeState();
}

class _NavigationHomeState extends State<NavigationHome> {
  int _selectedIndex = 0;
  final List<GlobalKey<NavigatorState>> _navigatorKeys = [
    GlobalKey<NavigatorState>(),
    GlobalKey<NavigatorState>(),
  ];

  final List<Widget> _screens = [
    Navigator(
      key: GlobalKey<NavigatorState>(),
      onGenerateRoute: (routeSettings) {
        return MaterialPageRoute(builder: (_) => HomeScreen());
      },
    ),
    Navigator(
      key: GlobalKey<NavigatorState>(),
      onGenerateRoute: (routeSettings) {
        return MaterialPageRoute(builder: (_) => ProfileScreen());
      },
    ),
  ];

  @override
  Widget build(BuildContext context) {
    return WillPopScope(
      onWillPop: () async {
        final isFirstRouteInCurrentTab =
            !await _navigatorKeys[_selectedIndex].currentState!.maybePop();
        return isFirstRouteInCurrentTab;
      },
      child: Scaffold(
        body: Stack(
          children: List.generate(_screens.length, (index) {
            return Offstage(
              offstage: _selectedIndex != index,
              child: Navigator(
                key: _navigatorKeys[index],
                onGenerateRoute: (settings) {
                  return MaterialPageRoute(
                    builder: (_) => index == 0
                        ? HomeScreen()
                        : ProfileScreen(),
                  );
                },
              ),
            );
          }),
        ),
        bottomNavigationBar: BottomNavigationBar(
          currentIndex: _selectedIndex,
          onTap: (index) => setState(() => _selectedIndex = index),
          items: const [
            BottomNavigationBarItem(icon: Icon(Icons.home), label: 'Home'),
            BottomNavigationBarItem(icon: Icon(Icons.person), label: 'Profile'),
          ],
        ),
      ),
    );
  }
}

3. screens/home_screen.dart

import 'package:flutter/material.dart';
import 'details_screen.dart';

class HomeScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text("Home")),
      body: Center(
        child: ElevatedButton(
          child: Text("Go to Details"),
          onPressed: () {
            Navigator.of(context).push(
              MaterialPageRoute(builder: (_) => DetailsScreen()),
            );
          },
        ),
      ),
    );
  }
}

4. screens/profile_screen.dart

import 'package:flutter/material.dart';

class ProfileScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text("Profile")),
      body: Center(child: Text("Profile Page")),
    );
  }
}

5. screens/details_screen.dart

import 'package:flutter/material.dart';

class DetailsScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text("Details")),
      body: Center(child: Text("This is a detail page")),
    );
  }
}

Nested navigation helps in preserving the navigation history of each tab separately, and is very helpful in modern apps like e-commerce, education, or dashboard systems.

For deeper architectural insights, consider checking Flutter’s official navigation documentation on flutter.dev.

rysasahrial

Leave a Reply

Your email address will not be published. Required fields are marked *