adaptive_scaffold_plus 1.1.0 copy "adaptive_scaffold_plus: ^1.1.0" to clipboard
adaptive_scaffold_plus: ^1.1.0 copied to clipboard

A production-ready replacement for flutter_adaptive_scaffold. Adapts navigation (BottomNavigationBar, NavigationRail, Drawer) per Material 3 guidelines.

adaptive_scaffold_plus #

A production-ready, community-maintained replacement for the discontinued flutter_adaptive_scaffold package. Drop it into any Flutter app to get navigation that automatically adapts to screen size, following Material 3 guidelines — with zero manual breakpoint logic.

Screen width Navigation shown
< 600px Bottom NavigationBar (docked) or a floating, frosted-glass pill bar
600–1200px NavigationRail (side)
> 1200px Permanent NavigationDrawer (full)

Resize the window / rotate the device and the transition animates automatically.


Install #

dependencies:
  adaptive_scaffold_plus: ^1.0.5
import 'package:adaptive_scaffold_plus/adaptive_scaffold_plus.dart';

Quick start #

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: AdaptiveScaffoldPlus(
        destinations: const [
          AdaptiveDestination(icon: Icons.home_outlined, selectedIcon: Icons.home, label: 'Home'),
          AdaptiveDestination(icon: Icons.search_outlined, selectedIcon: Icons.search, label: 'Search'),
          AdaptiveDestination(icon: Icons.person_outline, selectedIcon: Icons.person, label: 'Profile'),
        ],
        body: (index) => pages[index],
      ),
    );
  }
}

That's it — AdaptiveScaffoldPlus picks the right navigation widget for the current screen size and keeps body(selectedIndex) in sync with whichever destination is selected.


Floating, frosted-glass navigation bar #

By default the small-screen layout uses a standard, opaque NavigationBar docked to the bottom edge (AdaptiveNavigationStyle.docked). Set navigationStyle: AdaptiveNavigationStyle.floating to switch to a pill-shaped, translucent bar that floats above your content with blurred background — the modern look used by apps like Instagram.

AdaptiveScaffoldPlus(
  destinations: destinations,
  navigationStyle: AdaptiveNavigationStyle.floating,
  body: (index) => pages[index],
)

The bar automatically adapts its icon color to stay legible over both light and dark content, and shows an animated pill highlight behind the selected icon.

Tuning the floating bar #

AdaptiveScaffoldPlus(
  destinations: destinations,
  navigationStyle: AdaptiveNavigationStyle.floating,
  navigationBackgroundColor: Colors.black,   // tint of the glass surface
  floatingNavigationMargin: const EdgeInsets.fromLTRB(16, 0, 16, 16),
  floatingNavigationBlur: 30,                // frosted-glass blur strength
  floatingNavigationOpacity: 0.45,           // 0 = fully see-through, 1 = opaque
  floatingNavigationHeight: 56,
  body: (index) => pages[index],
)
Parameter Default Effect
navigationBackgroundColor white (light theme) / black (dark) Tint color of the glass surface
floatingNavigationMargin EdgeInsets.fromLTRB(16, 0, 16, 16) Space between the bar and the screen edges
floatingNavigationBlur 30 BackdropFilter blur sigma (frosted-glass strength)
floatingNavigationOpacity 0.45 Alpha of the tint color, 0–1
floatingNavigationHeight 56 Height of the bar itself

You can also use the bar standalone, outside of AdaptiveScaffoldPlus:

Scaffold(
  extendBody: true, // lets content scroll behind the floating bar
  body: MyContent(),
  bottomNavigationBar: SafeArea(
    minimum: const EdgeInsets.fromLTRB(16, 0, 16, 16),
    child: FloatingNavigationBar(
      destinations: destinations,
      selectedIndex: selectedIndex,
      onDestinationSelected: (i) => setState(() => selectedIndex = i),
    ),
  ),
)

Destinations #

Each nav item is an AdaptiveDestination — it maps to a NavigationBar / FloatingNavigationBar item on small screens, a NavigationRail item on medium screens, and a NavigationDrawer item on large screens.

AdaptiveDestination(
  icon: Icons.favorite_outline,
  selectedIcon: Icons.favorite,   // shown when selected; falls back to `icon`
  label: 'Favourites',
  tooltip: 'Your favourites',     // shown on long-press / hover
  badge: Text('3'),               // optional badge/notification content
)

At least 2 destinations are required.


Full AdaptiveScaffoldPlus reference #

AdaptiveScaffoldPlus(
  // Required
  destinations: [...],                    // List<AdaptiveDestination>, min 2
  body: (index) => pages[index],          // Widget Function(int selectedIndex)

  // Layout
  secondaryBody: (index) => detail[index],// optional second panel (list-detail pattern, large screens)
  appBar: AppBar(title: const Text('My App')),
  floatingActionButton: FloatingActionButton(onPressed: () {}, child: const Icon(Icons.add)),
  floatingActionButtonLocation: FloatingActionButtonLocation.endFloat,
  backgroundColor: Colors.white,
  resizeToAvoidBottomInset: true,

  // Selection
  initialIndex: 0,
  onDestinationSelected: (index) => print('selected $index'),

  // Breakpoints
  breakpoints: const AdaptiveBreakpoints(small: 600, large: 1200),

  // Medium screen (NavigationRail)
  railLabelType: NavigationRailLabelType.all,
  extendedRail: false,

  // Medium/large screen extras
  navigationHeader: const Text('MY APP'),  // shown above destinations
  navigationFooter: const Text('v1.0.5'),  // shown below destinations
  showNavigationDivider: true,

  // Styling shared across nav types
  navigationBackgroundColor: Colors.white,
  transitionDuration: const Duration(milliseconds: 200),

  // Small-screen navigation style (see "Floating" section above)
  navigationStyle: AdaptiveNavigationStyle.docked, // or .floating
  floatingNavigationMargin: const EdgeInsets.fromLTRB(16, 0, 16, 16),
  floatingNavigationBlur: 30,
  floatingNavigationOpacity: 0.45,
  floatingNavigationHeight: 56,
)

Custom breakpoints #

AdaptiveScaffoldPlus(
  breakpoints: const AdaptiveBreakpoints(small: 500, large: 1100),
  destinations: [...],
  body: (index) => pages[index],
)

You can also check the current size manually anywhere in your widget tree:

final size = Breakpoints.of(context); // ScreenSize.small / .medium / .large
if (Breakpoints.isSmall(context)) { ... }

List-detail pattern (large screens) #

AdaptiveScaffoldPlus(
  destinations: [...],
  body: (index) => MyListView(),
  secondaryBody: (index) => MyDetailView(), // shown beside body only on large screens
)

Low-level layout: AdaptiveLayout + SlotLayout #

For full control over what renders in each screen region (instead of the opinionated nav-bar/rail/drawer behavior of AdaptiveScaffoldPlus), compose AdaptiveLayout directly with per-breakpoint SlotLayouts:

AdaptiveLayout(
  body: SlotLayout(
    config: {
      ScreenSize.small: SlotLayoutConfig.from(child: MobilePage()),
      ScreenSize.large: SlotLayoutConfig.from(child: DesktopPage()),
    },
  ),
  primaryNavigation: SlotLayout(
    config: {
      ScreenSize.medium: SlotLayoutConfig.from(child: MyNavRail()),
      ScreenSize.large: SlotLayoutConfig.from(child: MyDrawer()),
    },
  ),
  topNavigation: SlotLayout(
    config: {
      ScreenSize.small: SlotLayoutConfig.from(child: AppBar(title: const Text('App'))),
    },
  ),
)

Slots: body, secondaryBody, primaryNavigation, secondaryNavigation, topNavigation, bottomNavigation — each is an optional SlotLayout that picks a child per ScreenSize, with a fade transition by default (override via SlotLayoutConfig.from(inAnimation: ..., outAnimation: ...)).


Try it locally #

A runnable demo lives in example/lib/main.dart:

cd example
flutter run -d chrome   # or any connected device/desktop target

Resize the window (or use responsive mode in Chrome DevTools) to see the layout switch between bottom bar, rail, and drawer live.


License #

See LICENSE.

3
likes
150
points
286
downloads

Documentation

API reference

Publisher

unverified uploader

Weekly Downloads

A production-ready replacement for flutter_adaptive_scaffold. Adapts navigation (BottomNavigationBar, NavigationRail, Drawer) per Material 3 guidelines.

Repository (GitHub)
View/report issues

Topics

#adaptive #scaffold #navigation #material3 #responsive

License

BSD-3-Clause (license)

Dependencies

flutter

More

Packages that depend on adaptive_scaffold_plus