Skip to content

Instantly share code, notes, and snippets.

@rodydavis
Created April 7, 2020 05:39
Show Gist options
  • Save rodydavis/5c7b3365ba9c4b010cace84ca20c2bcc to your computer and use it in GitHub Desktop.
Save rodydavis/5c7b3365ba9c4b010cace84ca20c2bcc to your computer and use it in GitHub Desktop.
Flutter Adaptive Scaffold
import 'package:flutter/material.dart';
const kTabletBreakpoint = 720.0;
const kDesktopBreakpoint = 1200.0;
const kSideMenuWidth = 250.0;
class AdaptiveScaffold extends StatelessWidget {
final List<TabItem> tabs;
final int selectedIndex;
final ValueChanged<int> onSelectionChanged;
const AdaptiveScaffold({
Key key,
@required this.tabs,
@required this.selectedIndex,
@required this.onSelectionChanged,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return LayoutBuilder(builder: (_, dimens) {
if (dimens.maxWidth >= kDesktopBreakpoint) {
return Material(
child: Row(
children: [
Container(
width: kSideMenuWidth,
child: ListView(
children: [
for (var i = 0; i < tabs.length; i++)
ListTile(
selected: selectedIndex == i,
title: Text(tabs[i].title),
leading: Icon(tabs[i].iconData),
onTap: () => onSelectionChanged(i),
),
],
),
),
Expanded(
child: buildBody(selectedIndex, tabs),
),
],
),
);
}
if (dimens.maxWidth >= kTabletBreakpoint) {
return Material(
child: Row(
children: [
NavigationRail(
selectedIconTheme: IconThemeData(
color: Theme.of(context).accentColor,
),
selectedLabelTextStyle: TextStyle(
color: Theme.of(context).accentColor,
),
labelType: NavigationRailLabelType.all,
selectedIndex: selectedIndex,
onDestinationSelected: (val) => onSelectionChanged(val),
destinations: [
for (final item in tabs)
NavigationRailDestination(
label: Text(item.title),
icon: Icon(item.iconData),
),
],
),
Expanded(
child: buildBody(selectedIndex, tabs),
),
],
),
);
}
return Scaffold(
body: buildBody(selectedIndex, tabs),
bottomNavigationBar: BottomNavigationBar(
type: BottomNavigationBarType.fixed,
currentIndex: selectedIndex,
onTap: (val) => onSelectionChanged(val),
backgroundColor: Theme.of(context).scaffoldBackgroundColor,
items: [
for (final item in tabs)
BottomNavigationBarItem(
title: Text(item.title),
icon: Icon(item.iconData),
),
],
),
);
});
}
Widget buildBody(int selectedIndex, List<TabItem> tabs) {
return IndexedStack(
index: selectedIndex,
children: [
for (final item in tabs) item.body,
],
);
}
}
class TabItem {
final Widget body;
final String title;
final IconData iconData;
TabItem({
@required this.body,
@required this.title,
@required this.iconData,
});
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment