Skip to content

JustTryAI/adaptive_navigation

 
 

Repository files navigation

Adaptive Navigation

pub package license

Beautiful responsive navigation that automatically adapts between ConvexAppBar (mobile) and NavigationRail (desktop) based on screen size.

✨ Features

  • 📱 Adaptive Layout: Automatically switches between mobile and desktop navigation
  • 🎨 Beautiful Design: Convex bottom bar on mobile, rail navigation on desktop
  • 🔔 Smart Badges: Hide when viewing, reappear when needed, clear permanently
  • 🎯 Multiple Styles: fixed, fixedCircle, react, reactCircle, textIn, titled, flip
  • 🌈 Full Customization: Colors, gradients, elevation, corner radius, and more
  • High Performance: Smooth animations, no lag
  • 🌍 Cross-Platform: iOS, Android, Web, Desktop (Windows, macOS, Linux)

📱 Preview

Mobile (< 600px): ConvexAppBar at bottom Desktop (≥ 600px): NavigationRail on side

[Add screenshots/GIFs here]

🚀 Quick Start

Installation

Add to your pubspec.yaml:

dependencies:
  adaptive_navigation: ^1.0.0

Basic Usage

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

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

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: 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: _buildContent(),
      ),
    );
  }

  Widget _buildContent() {
    return Center(child: Text('Page $_selectedIndex'));
  }
}

That's it! Your app now has adaptive navigation! 🎉

🔔 With Badges

class _MyAppState extends State<MyApp> {
  int _selectedIndex = 0;
  final Map<int, dynamic> _badges = {1: '5', 2: '99+'};

  Map<int, dynamic> get _visibleBadges {
    final visible = Map.from(_badges);
    visible.remove(_selectedIndex);  // Hide badge for active tab
    return visible;
  }

  @override
  Widget build(BuildContext context) {
    return AdaptiveConvexNavigation.badge(
      _visibleBadges,
      selectedIndex: _selectedIndex,
      onTap: (index) => setState(() => _selectedIndex = index),
      badgeColor: Colors.red,
      badgeTextColor: Colors.white,
      items: const [
        TabItem(icon: Icons.home, title: 'Home'),
        TabItem(icon: Icons.message, title: 'Messages'),
        TabItem(icon: Icons.notifications, title: 'Alerts'),
      ],
      child: _buildContent(),
    );
  }
}

🎨 Custom Styling

AdaptiveConvexNavigation(
  selectedIndex: _selectedIndex,
  onTap: _handleTap,
  breakpoint: 800,  // Custom breakpoint
  
  // Mobile styling
  convexStyle: TabStyle.react,
  backgroundColor: Colors.deepPurple,
  activeColor: Colors.white,
  gradient: LinearGradient(colors: [Colors.purple, Colors.blue]),
  
  // Desktop styling
  railBackgroundColor: Colors.deepPurple,
  railLabelType: NavigationRailLabelType.all,
  
  items: const [...],
  child: MyContent(),
)

📚 Documentation

🎯 Use Cases

Perfect for:

  • 📱 Mobile apps that need tablet support
  • 💻 Web apps with desktop layouts
  • 🌐 Cross-platform apps (iOS, Android, Web, Desktop)
  • 📧 Messaging and social media apps with notifications
  • 🛒 E-commerce apps with cart badges
  • 📊 Dashboard apps with multiple views

🌟 What Makes It Special

Automatic Adaptation

No need for manual LayoutBuilder or responsive code. The widget handles everything:

// Before: Manual responsive code (30+ lines)
LayoutBuilder(
  builder: (context, constraints) {
    if (constraints.maxWidth >= 600) {
      return Row([NavigationRail(...), Content()]);
    } else {
      return Scaffold(body: Content(), bottomNavigationBar: ConvexAppBar(...));
    }
  },
)

// After: One widget (10 lines)
AdaptiveConvexNavigation(
  selectedIndex: _selectedIndex,
  onTap: _handleTap,
  items: [...],
  child: Content(),
)

Smart Badge Behavior

Badges hide when you're viewing that tab, reappear when you navigate away:

  • Click Messages → badge hides (you're viewing it)
  • Click Home → Messages badge reappears (still unread)
  • Click "Clear" → badge disappears permanently

Beautiful on All Platforms

  • iOS: Smooth animations, respects safe areas
  • Android: Material Design guidelines
  • Web: Responsive at all breakpoints
  • Desktop: Professional navigation rail

🛠️ Advanced Features

  • ✅ TabController integration for PageView/TabBarView
  • ✅ Custom chip builders for advanced badge designs
  • ✅ Event blocking with onTapNotify
  • ✅ Corner radius support (fixed styles)
  • ✅ Gradient backgrounds
  • ✅ Custom breakpoints
  • ✅ Independent mobile/desktop styling

📦 What's Included

  • AdaptiveConvexNavigation - Main adaptive widget
  • ConvexAppBar - Beautiful bottom navigation bar
  • TabItem - Navigation item configuration
  • ChipBuilder - Badge customization
  • Multiple tab styles and themes

🤝 Contributing

Contributions are welcome! Please read the contributing guidelines first.

📄 License

Apache License 2.0

Original ConvexAppBar by Chaobin Wu
AdaptiveConvexNavigation and additional features by contributors

🙏 Credits

Based on the original convex_bottom_bar package.

📞 Support


Made with ❤️ for the Flutter community

About

Update the Convex bottom bar

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • Dart 59.6%
  • C++ 17.6%
  • CMake 14.5%
  • Ruby 2.4%
  • Swift 2.2%
  • C 1.7%
  • Other 2.0%