fold_adaptive_nav 1.1.0
fold_adaptive_nav: ^1.1.0 copied to clipboard
Detects foldables and their posture on iOS and Android, and adapts navigation by itself: bottom bar on phones, thumb rail on cover displays, tablet layouts when open.
example/lib/main.dart
import 'package:flutter/material.dart';
import 'package:fold_adaptive_nav/fold_adaptive_nav.dart';
import 'device_page.dart';
import 'settings_page.dart';
import 'transfer_page.dart';
void main() {
// No SystemChrome.setPreferredOrientations here: FoldScope sets them once
// the first fold reading arrives.
runApp(const ExampleApp());
}
class ExampleApp extends StatefulWidget {
const ExampleApp({super.key});
@override
State<ExampleApp> createState() => _ExampleAppState();
}
class _ExampleAppState extends State<ExampleApp> {
var _settings = const ExampleSettings();
@override
Widget build(BuildContext context) {
return FoldScope(
config: _settings.config,
child: MaterialApp(
title: 'fold_adaptive_nav',
debugShowCheckedModeBanner: false,
theme: ThemeData(colorSchemeSeed: Colors.teal),
darkTheme: ThemeData(
colorSchemeSeed: Colors.teal,
brightness: Brightness.dark,
),
locale: _settings.rtl ? const Locale('ar') : null,
// Pins the form factor below this point, to preview the cover and
// tablet layouts on any device.
builder: (context, child) {
Widget app = child!;
if (_settings.preview case final FormFactor preview) {
app = FormFactorOverride(formFactor: preview, child: app);
}
return Directionality(
textDirection: _settings.rtl ? TextDirection.rtl : TextDirection.ltr,
child: app,
);
},
home: HomeShell(
settings: _settings,
onSettingsChanged: (s) => setState(() => _settings = s),
),
),
);
}
}
class HomeShell extends StatefulWidget {
const HomeShell({
super.key,
required this.settings,
required this.onSettingsChanged,
});
final ExampleSettings settings;
final ValueChanged<ExampleSettings> onSettingsChanged;
@override
State<HomeShell> createState() => _HomeShellState();
}
class _HomeShellState extends State<HomeShell> {
int _tab = 0;
static const _destinations = [
NavDestination(
icon: Icons.devices_fold_outlined,
selectedIcon: Icons.devices_fold,
label: 'Device',
),
NavDestination(
icon: Icons.swap_horiz_outlined,
selectedIcon: Icons.swap_horiz,
label: 'Transfer',
),
NavDestination(
icon: Icons.tune_outlined,
selectedIcon: Icons.tune,
label: 'Settings',
),
];
@override
Widget build(BuildContext context) {
return AdaptiveNavScaffold(
destinations: _destinations,
currentIndex: _tab,
onSelect: (i) => setState(() => _tab = i),
// A FAB on phones and tablets, the foot of the rail on the cover display.
trailingAction: FloatingActionButton(
tooltip: 'Scan',
onPressed: () => ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('Scan tapped')),
),
child: const Icon(Icons.qr_code_scanner),
),
body: IndexedStack(
index: _tab,
children: [
const DevicePage(),
const TransferPage(),
SettingsPage(
settings: widget.settings,
onChanged: widget.onSettingsChanged,
),
],
),
);
}
}