Created
April 7, 2020 05:39
-
-
Save rodydavis/5c7b3365ba9c4b010cace84ca20c2bcc to your computer and use it in GitHub Desktop.
Flutter Adaptive Scaffold
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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