adaptive_scaffold_plus 1.0.9
adaptive_scaffold_plus: ^1.0.9 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 Flutter package that automatically adapts your app's navigation to the current screen size, following Material 3 guidelines.
Drop-in replacement for the discontinued flutter_adaptive_scaffold — built with Dart 3, full Material 3 support, and zero extra dependencies.
How it works #
Resize your window and the navigation changes automatically — no manual breakpoint checks needed.
Phone (< 600px) → NavigationBar (bottom)
Tablet (600–1200px) → NavigationRail (left side)
Desktop (> 1200px) → NavigationDrawer (permanent panel)
Installation #
dependencies:
adaptive_scaffold_plus: ^1.0.6
import 'package:adaptive_scaffold_plus/adaptive_scaffold_plus.dart';
Quick start #
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],
)
Features #
- Auto-adaptive navigation — bottom bar, rail, or drawer based on screen width
- Material 3 — uses
NavigationBar,NavigationRail, andNavigationDrawer - Selected color — icon and label both change color when selected
- Selection indicator — bordered rounded-rectangle indicator on selected item
- Full nav border — optional border + border radius around the entire nav component
- Custom breakpoints — override the default 600 / 1200 px thresholds
- List-detail layout — optional
secondaryBodypanel on large screens - Badges — notification badges on any destination
- Nav header / footer — widgets above and below the destination list
- Animated transitions —
AnimatedSwitcheron body page changes - Zero extra dependencies — only Flutter SDK
AdaptiveScaffoldPlus parameters #
Required #
| Parameter | Type | Description |
|---|---|---|
destinations |
List<AdaptiveDestination> |
Navigation items. Minimum 2. |
body |
Widget Function(int index) |
Page builder, receives the selected index. |
Navigation #
| Parameter | Type | Default | Description |
|---|---|---|---|
initialIndex |
int |
0 |
Starting selected destination. |
onDestinationSelected |
ValueChanged<int>? |
— | Callback when user taps a destination. |
breakpoints |
AdaptiveBreakpoints |
AdaptiveBreakpoints() |
Custom small/large thresholds. |
railLabelType |
NavigationRailLabelType |
.all |
Label visibility on the rail. |
extendedRail |
bool |
false |
Show labels beside icons on medium screens. |
Layout #
| Parameter | Type | Default | Description |
|---|---|---|---|
appBar |
PreferredSizeWidget? |
— | AppBar shown at the top. |
secondaryBody |
Widget Function(int)? |
— | Detail panel shown beside body on large screens. |
floatingActionButton |
Widget? |
— | FAB widget. |
floatingActionButtonLocation |
FloatingActionButtonLocation? |
— | FAB position. |
resizeToAvoidBottomInset |
bool? |
— | Whether body resizes when keyboard appears. |
Appearance #
| Parameter | Type | Default | Description |
|---|---|---|---|
backgroundColor |
Color? |
— | Scaffold background color. |
navigationBackgroundColor |
Color? |
— | Background color of the nav component. |
showNavigationDivider |
bool |
true |
Divider line between nav and body. |
transitionDuration |
Duration |
200ms |
Body page switch animation duration. |
navigationHeader |
Widget? |
— | Widget shown above destinations. |
navigationFooter |
Widget? |
— | Widget shown below destinations. |
Selected item styling #
| Parameter | Type | Default | Description |
|---|---|---|---|
selectedColor |
Color? |
ColorScheme.primary |
Color for the selected icon and label. |
indicatorBorderRadius |
double |
12 |
Corner radius of the selection indicator. |
Navigation container border #
| Parameter | Type | Default | Description |
|---|---|---|---|
navigationBorderColor |
Color? |
null |
Border color drawn around the full nav component. |
navigationBorderWidth |
double |
1.0 |
Border stroke width. |
navigationBorderRadius |
BorderRadius? |
null |
Rounds all corners of the nav container. |
AdaptiveDestination #
AdaptiveDestination(
icon: Icons.home_outlined, // unselected icon (required)
label: 'Home', // label text (required)
selectedIcon: Icons.home, // selected icon (optional, falls back to icon)
tooltip: 'Go to Home', // hover/long-press tooltip
badge: const Text('3'), // notification badge
)
Breakpoints #
// Static helpers — use anywhere you have a BuildContext
Breakpoints.isSmall(context) // width < 600
Breakpoints.isMedium(context) // 600 ≤ width < 1200
Breakpoints.isLarge(context) // width ≥ 1200
Breakpoints.of(context) // → ScreenSize.small / .medium / .large
// Custom thresholds
AdaptiveScaffoldPlus(
breakpoints: AdaptiveBreakpoints(small: 480, large: 1024),
...
)
Examples #
Border + rounded corners on the nav bar #
AdaptiveScaffoldPlus(
destinations: _destinations,
body: (i) => pages[i],
navigationBorderColor: Colors.grey.shade300,
navigationBorderWidth: 1.5,
navigationBorderRadius: BorderRadius.circular(16),
)
Custom selected color + indicator style #
AdaptiveScaffoldPlus(
destinations: _destinations,
body: (i) => pages[i],
selectedColor: Colors.deepPurple,
indicatorBorderRadius: 10,
navigationBorderColor: Colors.deepPurple,
navigationBorderWidth: 2,
navigationBorderRadius: BorderRadius.circular(20),
)
List-detail layout (large screens) #
AdaptiveScaffoldPlus(
destinations: _destinations,
body: (i) => MyListView(i), // left panel
secondaryBody: (i) => MyDetailView(i), // right panel — visible on large only
)
Nav header + footer #
AdaptiveScaffoldPlus(
destinations: _destinations,
body: (i) => pages[i],
navigationHeader: const Padding(
padding: EdgeInsets.all(16),
child: Text('MY APP', style: TextStyle(fontWeight: FontWeight.bold)),
),
navigationFooter: ListTile(
leading: const Icon(Icons.logout),
title: const Text('Logout'),
onTap: () {},
),
)
Destination with badge #
AdaptiveDestination(
icon: Icons.notifications_outlined,
selectedIcon: Icons.notifications,
label: 'Alerts',
badge: const Text('5'),
)
Extended rail (labels beside icons) #
AdaptiveScaffoldPlus(
destinations: _destinations,
body: (i) => pages[i],
extendedRail: true,
railLabelType: NavigationRailLabelType.none,
)
Low-level API #
For full layout control, use AdaptiveLayout with SlotLayout slots:
AdaptiveLayout(
primaryNavigation: SlotLayout(
config: {
ScreenSize.medium: SlotLayoutConfig.from(child: MyRail()),
ScreenSize.large: SlotLayoutConfig.from(child: MyDrawer()),
},
),
body: SlotLayout(
config: {
ScreenSize.small: SlotLayoutConfig.from(child: MobilePage()),
ScreenSize.large: SlotLayoutConfig.from(child: DesktopPage()),
},
),
)
Migration from flutter_adaptive_scaffold #
flutter_adaptive_scaffold was discontinued. Replace it like this:
// Before
import 'package:flutter_adaptive_scaffold/flutter_adaptive_scaffold.dart';
AdaptiveScaffold(...)
// After
import 'package:adaptive_scaffold_plus/adaptive_scaffold_plus.dart';
AdaptiveScaffoldPlus(...)
The core API (destinations, body) is the same. Additional parameters are opt-in.
Requirements #
- Dart
>=3.0.0 - Flutter
>=3.10.0
License #
BSD 3-Clause — see LICENSE.