Flutter AppBar Drawer BottomNav

Most apps have more than one screen. Navigation is how you move between them. Flutter uses a stack-based system called the Navigator to manage screens, and a route system to define paths between them.

How Flutter Navigation Works

Flutter's Navigator works like a stack of plates. Each new screen you open goes on top. When you go back, the top plate is removed and you see the one below.

  NAVIGATOR STACK

  ┌─────────────────────┐  ← Active (user sees this)
  │   Product Detail    │
  ├─────────────────────┤
  │   Product List      │
  ├─────────────────────┤
  │   Home Screen       │  ← Bottom of stack
  └─────────────────────┘

  Push → add a screen on top
  Pop  → remove the top screen (go back)

Basic Navigation — Push and Pop

Push: Go to a New Screen

ElevatedButton(
  onPressed: () {
    Navigator.push(
      context,
      MaterialPageRoute(builder: (context) => DetailScreen()),
    );
  },
  child: Text('View Details'),
)

Pop: Go Back

ElevatedButton(
  onPressed: () {
    Navigator.pop(context);
  },
  child: Text('Go Back'),
)

Passing Data Between Screens

Pass data to the next screen through the constructor, just like passing arguments to a function.

// Screen 1 — Send data
Navigator.push(
  context,
  MaterialPageRoute(
    builder: (context) => ProductDetail(productName: 'Running Shoes', price: 2499),
  ),
);

// Screen 2 — Receive data
class ProductDetail extends StatelessWidget {
  final String productName;
  final int price;

  const ProductDetail({required this.productName, required this.price});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text(productName)),
      body: Center(child: Text('Price: ₹$price')),
    );
  }
}

Returning Data Back to Previous Screen

// On Screen 2 — Pop with a result
Navigator.pop(context, 'Item added to cart');

// On Screen 1 — Await the result
String? result = await Navigator.push(
  context,
  MaterialPageRoute(builder: (context) => Screen2()),
);

print(result);  // 'Item added to cart'

Named Routes

For larger apps, named routes keep navigation clean and centralized. You define all route paths in one place.

  App routes map:
  ────────────────────────────────────
  '/'        → HomeScreen
  '/login'   → LoginScreen
  '/profile' → ProfileScreen
  '/details' → DetailScreen
MaterialApp(
  initialRoute: '/',
  routes: {
    '/': (context) => HomeScreen(),
    '/login': (context) => LoginScreen(),
    '/profile': (context) => ProfileScreen(),
  },
)
// Navigate using the route name
Navigator.pushNamed(context, '/profile');

// Go back
Navigator.pop(context);

pushNamed vs push

MethodBest For
Navigator.push()Small apps, passing constructor data easily
Navigator.pushNamed()Larger apps, clean route management

Replace or Clear the Stack

pushReplacement — Replace Current Screen

Use this after login: replace the login screen with the home screen so the user cannot tap Back to return to login.

Navigator.pushReplacement(
  context,
  MaterialPageRoute(builder: (context) => HomeScreen()),
);

pushAndRemoveUntil — Clear Entire Stack

Use this for logout: remove all screens and start fresh.

Navigator.pushAndRemoveUntil(
  context,
  MaterialPageRoute(builder: (context) => LoginScreen()),
  (route) => false,  // false removes all previous routes
);
  After logout:
  Stack before:  [Login] [Home] [Profile] [Settings]
  Stack after:   [Login]   ← only login remains

go_router — Modern Navigation Package

For advanced apps with deep links and complex routing, the go_router package (officially recommended by Flutter) offers a URL-style navigation system.

  Route definitions:
  ──────────────────────────────────
  /home        → HomeScreen
  /product/:id → ProductDetail (with dynamic ID)
  /cart        → CartScreen
// Add to pubspec.yaml
dependencies:
  go_router: ^latest_version

// Navigate
context.go('/product/42');
context.go('/cart');

Navigation Best Practices

  • Use pushReplacement after login so users cannot go back to the login screen.
  • Prefer named routes or go_router as the app grows beyond 3-4 screens.
  • Always pass only the data a screen needs — avoid passing entire objects when one field will do.
  • Use pushAndRemoveUntil on logout to clear all session-specific screens from the stack.

Leave a Comment

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