Skip to content

Latest commit

Β 

History

History
409 lines (337 loc) Β· 12 KB

ADAPTIVE_NAVIGATION.md

File metadata and controls

409 lines (337 loc) Β· 12 KB

🎯 AdaptiveConvexNavigation - Responsive Navigation Made Easy

Overview

AdaptiveConvexNavigation is a self-contained, drop-in widget that automatically provides responsive navigation for your Flutter app. It intelligently switches between mobile and desktop layouts without requiring any manual responsive code.

πŸ“± Mobile Layout (< 600px)

Uses the beautiful ConvexAppBar at the bottom of the screen with its signature convex shape.

πŸ’» Desktop Layout (β‰₯ 600px)

Uses NavigationRail on the side, providing a professional desktop experience.

✨ Key Features

  • βœ… Zero Configuration - Works out of the box with sensible defaults
  • βœ… Fully Customizable - All ConvexAppBar and NavigationRail properties available
  • βœ… Badge Support - Show notifications and counters on navigation items
  • βœ… All Styles - Supports all ConvexAppBar styles (react, fixed, circle, etc.)
  • βœ… Theming - Full theming support including gradients
  • βœ… Self-Contained - No need for LayoutBuilder or manual responsive code
  • βœ… Cross-Platform - Works seamlessly on iOS, Android, Web, and Desktop

πŸš€ Quick Start

Basic Usage

import 'package:convex_bottom_bar_renew/convex_bottom_bar_renew.dart';

class MyApp extends StatefulWidget {
  @override
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  int _selectedIndex = 0;

  @override
  Widget build(BuildContext context) {
    return AdaptiveConvexNavigation(
      selectedIndex: _selectedIndex,
      onTap: (index) => setState(() => _selectedIndex = index),
      items: const [
        TabItem(icon: Icons.home, title: 'Home'),
        TabItem(icon: Icons.search, title: 'Search'),
        TabItem(icon: Icons.person, title: 'Profile'),
      ],
      child: Scaffold(
        appBar: AppBar(title: const Text('My App')),
        body: Center(child: Text('Page $_selectedIndex')),
      ),
    );
  }
}

That's it! Your app now has responsive navigation. πŸŽ‰

🎨 Styling

Consistent Styling Across Both Layouts

AdaptiveConvexNavigation(
  selectedIndex: _selectedIndex,
  onTap: _onNavigationItemSelected,
  // Mobile styling
  convexStyle: TabStyle.react,
  backgroundColor: Colors.blue,
  activeColor: Colors.white,
  color: Colors.white70,
  // Desktop styling (uses mobile colors as fallback)
  railBackgroundColor: Colors.blue,
  railSelectedIconTheme: const IconThemeData(color: Colors.white),
  railUnselectedIconTheme: const IconThemeData(color: Colors.white70),
  items: const [
    TabItem(icon: Icons.home, title: 'Home'),
    TabItem(icon: Icons.search, title: 'Search'),
    TabItem(icon: Icons.person, title: 'Profile'),
  ],
  child: YourContentWidget(),
)

Different Styles for Mobile vs Desktop

AdaptiveConvexNavigation(
  // Mobile: Fun, colorful convex bar
  convexStyle: TabStyle.reactCircle,
  backgroundColor: Colors.deepPurple,
  gradient: LinearGradient(
    colors: [Colors.purple, Colors.blue],
  ),
  // Desktop: Professional, minimalist rail
  railBackgroundColor: Colors.grey[900],
  railLabelType: NavigationRailLabelType.selected,
  railUseIndicator: true,
  // ... rest of config
)

πŸ”” Badge Support

Show notifications, counters, or indicators on your navigation items:

AdaptiveConvexNavigation.badge(
  {
    0: '5',              // Text badge: "5 new items"
    1: '99+',            // Text badge: "99+ notifications"
    2: Icons.circle,     // Icon badge: simple dot indicator
  },
  selectedIndex: _selectedIndex,
  onTap: _onNavigationItemSelected,
  // Badge styling
  badgeColor: Colors.red,
  badgeTextColor: Colors.white,
  badgePadding: const EdgeInsets.symmetric(horizontal: 6, vertical: 2),
  badgeMargin: const EdgeInsets.only(top: 8, right: 8),
  badgeBorderRadius: 12,
  // Navigation items
  items: const [
    TabItem(icon: Icons.message, title: 'Messages'),
    TabItem(icon: Icons.notifications, title: 'Alerts'),
    TabItem(icon: Icons.person, title: 'Profile'),
  ],
  child: YourContentWidget(),
)

βš™οΈ Configuration

Custom Breakpoint

Change when the layout switches:

AdaptiveConvexNavigation(
  breakpoint: 800,  // Switch at 800px instead of default 600px
  // ... rest of config
)

All ConvexAppBar Features

All standard ConvexAppBar features work in adaptive mode:

  • βœ… Styles: fixed, fixedCircle, react, reactCircle, textIn, titled, flip
  • βœ… Theming: Colors, gradients, shadows
  • βœ… Customization: Height, curve size, elevation, corner radius
  • βœ… Badges: Custom badge builders
  • βœ… Controllers: TabController integration
  • βœ… Callbacks: onTap, onTapNotify

NavigationRail Customization

Full control over the desktop NavigationRail:

AdaptiveConvexNavigation(
  // Rail-specific properties
  railLabelType: NavigationRailLabelType.all,  // none, selected, all
  railExtended: false,                          // Expand rail to show labels inline
  railUseIndicator: true,                       // Show selection indicator
  railIndicatorColor: Colors.blue.shade100,     // Indicator color
  railLeading: MyLogoWidget(),                  // Widget at top of rail
  railTrailing: MySettingsWidget(),             // Widget at bottom of rail
  railMinWidth: 72,                             // Minimum rail width
  railElevation: 4,                             // Rail shadow elevation
  // ... rest of config
)

πŸ“‹ Complete API Reference

Core Properties

Property Type Description
child Widget Required. The content to display in the main area
items List<TabItem> Required. Navigation items
selectedIndex int Required. Currently selected index
onTap Function(int) Callback when item is tapped
breakpoint double Screen width threshold (default: 600)

ConvexAppBar Properties (Mobile)

Property Type Description
convexStyle TabStyle Tab style (default: reactCircle)
backgroundColor Color Background color
color Color Inactive item color
activeColor Color Active item color
gradient Gradient Gradient background
height double AppBar height
curveSize double Convex curve size
elevation double Shadow elevation
cornerRadius double Corner radius (fixed styles)
chipBuilder ChipBuilder Custom badge builder

NavigationRail Properties (Desktop)

Property Type Description
railBackgroundColor Color Background color
railLabelType NavigationRailLabelType Label display type
railSelectedIconTheme IconThemeData Selected icon theme
railUnselectedIconTheme IconThemeData Unselected icon theme
railUseIndicator bool Show selection indicator
railIndicatorColor Color Indicator color
railExtended bool Expand rail width
railLeading Widget Widget at top
railTrailing Widget Widget at bottom
railMinWidth double Minimum width
railElevation double Shadow elevation

🎯 Use Cases

1. Mobile App with Tablet Support

// Automatically adapts between phone and tablet layouts
AdaptiveConvexNavigation(
  breakpoint: 600,  // Standard tablet breakpoint
  // ... config
)

2. Web App with Desktop Support

// Responsive web app that works on all screen sizes
AdaptiveConvexNavigation(
  breakpoint: 900,  // Larger breakpoint for web
  // ... config
)

3. Cross-Platform App

// One widget, works everywhere
AdaptiveConvexNavigation(
  // iOS/Android: ConvexAppBar
  // iPad/Tablet: NavigationRail
  // Web/Desktop: NavigationRail
  // ... config
)

πŸ”„ Migration Guide

Before: Manual Responsive Code

// OLD: Manual responsive layout (30+ lines)
Widget build(BuildContext context) {
  return LayoutBuilder(
    builder: (context, constraints) {
      final isWideScreen = constraints.maxWidth >= 600;
      
      if (isWideScreen) {
        return Row(
          children: [
            NavigationRail(
              selectedIndex: _selectedIndex,
              onDestinationSelected: _onNavigationItemSelected,
              destinations: [
                NavigationRailDestination(icon: Icon(Icons.home), label: Text('Home')),
                NavigationRailDestination(icon: Icon(Icons.search), label: Text('Search')),
              ],
            ),
            VerticalDivider(thickness: 1, width: 1),
            Expanded(child: _buildContent()),
          ],
        );
      } else {
        return Scaffold(
          body: _buildContent(),
          bottomNavigationBar: ConvexAppBar(
            items: [
              TabItem(icon: Icons.home, title: 'Home'),
              TabItem(icon: Icons.search, title: 'Search'),
            ],
            initialActiveIndex: _selectedIndex,
            onTap: _onNavigationItemSelected,
          ),
        );
      }
    },
  );
}

After: AdaptiveConvexNavigation

// NEW: Clean, simple, self-contained (10 lines)
Widget build(BuildContext context) {
  return AdaptiveConvexNavigation(
    selectedIndex: _selectedIndex,
    onTap: _onNavigationItemSelected,
    items: const [
      TabItem(icon: Icons.home, title: 'Home'),
      TabItem(icon: Icons.search, title: 'Search'),
    ],
    child: _buildContent(),
  );
}

Result: 70% less code, easier to maintain, more features! πŸŽ‰

πŸ“± Platform Behavior

Platform < Breakpoint β‰₯ Breakpoint
iOS ConvexAppBar NavigationRail
Android ConvexAppBar NavigationRail
Web ConvexAppBar NavigationRail
macOS ConvexAppBar NavigationRail
Windows ConvexAppBar NavigationRail
Linux ConvexAppBar NavigationRail

πŸŽ“ Examples

Check out the example app for complete demonstrations:

cd example
flutter run

Files:

  • example/lib/main.dart - Basic adaptive navigation
  • example/lib/adaptive_badge_example.dart - Advanced features with badges

Try it:

  1. Run the app
  2. Resize the window
  3. Watch the navigation adapt automatically!

πŸ’‘ Tips & Best Practices

1. Consistent Colors

Use the same colors for both layouts for a cohesive experience:

const primaryColor = Colors.blue;
const activeColor = Colors.white;

AdaptiveConvexNavigation(
  backgroundColor: primaryColor,
  railBackgroundColor: primaryColor,
  activeColor: activeColor,
  railSelectedIconTheme: IconThemeData(color: activeColor),
  // ...
)

2. Appropriate Breakpoints

  • Mobile-first apps: 600px (default)
  • Web apps: 900px or higher
  • Tablet-optimized: 768px

3. Test on Real Devices

While the widget adapts automatically, always test on:

  • Small phones (< 400px)
  • Large phones (400-600px)
  • Tablets (600-900px)
  • Desktop (> 900px)

4. Consider Content Layout

The NavigationRail takes horizontal space. Ensure your content adapts:

child: Scaffold(
  appBar: AppBar(title: const Text('My App')),
  body: LayoutBuilder(
    builder: (context, constraints) {
      // Your content can also adapt based on available space
      return YourResponsiveContent(width: constraints.maxWidth);
    },
  ),
)

πŸ› Troubleshooting

Issue: Badge not showing on NavigationRail

Note: NavigationRail has limited badge support in the current implementation. Badges work fully on ConvexAppBar (mobile). Desktop badge support is planned for a future update.

Issue: Layout not switching at breakpoint

Solution: Ensure the widget has access to the full screen width. If wrapped in a constrained container, it will use that width instead.

Issue: Colors not matching between layouts

Solution: Set both mobile and desktop color properties explicitly:

backgroundColor: Colors.blue,
railBackgroundColor: Colors.blue,

πŸ“„ License

Same as the main package - Apache License 2.0

🀝 Contributing

Found a bug or have a feature request? Please open an issue on GitHub!


Made with ❀️ for the Flutter community