Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save AleksandarSavic95/af4f37751570e67876264e0d8e3d53cf to your computer and use it in GitHub Desktop.
Save AleksandarSavic95/af4f37751570e67876264e0d8e3d53cf to your computer and use it in GitHub Desktop.
Bottom APP bar done via Stack widget - issue: no Notched FAB available.. `Stack` helps move the BottomAppBar down below the line of SafeArea by using a negative value for `Positioned`'s `bottom` property.
// Bottom APP bar done via Stack widget - issue: no Notched FAB available..
// `Stack` helps move the BottomAppBar down below the line of SafeArea by
// using a negative value for `Positioned`'s `bottom` property.
//
//// TAKEN FROM:
// SafeArea around Scaffold with BottomNavigationBar -> How to remove Bar elevation?
// https://github.com/flutter/flutter/issues/21688
import 'package:flutter/material.dart';
class MyHomePage extends StatefulWidget {
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
int _selectedIndex = 0;
void _selectedTab(int index) {
setState(() {
_selectedIndex = index;
});
}
@override
Widget build(BuildContext context) {
return new Container(
color: Colors.white,
child: Scaffold(
backgroundColor: Colors.red,
body: SafeArea(
bottom: false,
child: Stack(children: [
// Column(mainAxisSize: MainAxisSize.max, children: [
_screenContent(),
// SizedBox(height: 400),
// Stack(alignment: Alignment.center, children: [
Positioned(
bottom: -30.0,
left: 0.0,
right: 0.0,
child: FABBottomAppBar(
onTabSelected: _selectedTab,
selectedIndex: _selectedIndex,
),
),
// ]),
]),
),
),
);
}
Widget _screenContent() {
// return Center(child: Text('_selectedIndex: $_selectedIndex'));
return Column(
children: [
Expanded(
child: Center(
child: Text('_selectedIndex: $_selectedIndex'),
),
),
],
crossAxisAlignment: CrossAxisAlignment.stretch,
);
}
}
void main() {
runApp(
MaterialApp(
home: Builder(builder: (BuildContext context) {
final MediaQueryData data = MediaQuery.of(context);
// MediaQuery padding for a fake bottom "notch"
return MediaQuery(
data: data.copyWith(padding: data.padding.copyWith(bottom: 34.0)),
child: MyHomePage(),
);
}),
),
);
}
class FABBottomAppBarItem {
FABBottomAppBarItem({this.iconName});
IconData iconName;
}
class FABBottomAppBar extends StatelessWidget {
FABBottomAppBar({
this.selectedIndex,
this.onTabSelected,
});
final List<FABBottomAppBarItem> items = [
FABBottomAppBarItem(iconName: Icons.home),
FABBottomAppBarItem(iconName: Icons.palette),
FABBottomAppBarItem(iconName: Icons.games),
FABBottomAppBarItem(iconName: Icons.admin_panel_settings),
];
final int selectedIndex;
final ValueChanged<int> onTabSelected;
final double _kAppBarHeight = 70.0;
final double _kIconShadowWidth = 54.0;
final double _kIconShadowHeight = 44.0;
final double _notchMargin = 9.0;
// 70 - 44 = 26 ~~~ 26 / 2 = 13
// 70 - 24 = 46 ~~~ 46 / 2 = 23
// final double _kItemPaddingVertical = 23.0;
final Color _kBackgroundColor = Colors.blue;
final Color _kIconColor = Colors.grey;
final Color _kSelectedIconColor = Colors.pink;
@override
Widget build(BuildContext context) {
List<Widget> items = List.generate(this.items.length, (int index) {
return _buildTabItem(
item: this.items[index],
index: index,
onPressed: this.onTabSelected,
);
});
// insert spacing between the first two and last two tabs
items.insert(2, _buildSpacingTabItem());
// keep appbar items centered vertically while increasing the height
// double verticalMargin = 0.0;
double appBarHeight = _kAppBarHeight;
CrossAxisAlignment appBarItemsCrossAlignment = CrossAxisAlignment.center;
if (MediaQuery.of(context).padding.bottom > 0) {
print('MediaQuery.of(context).padding.bottom = ' +
MediaQuery.of(context).padding.bottom.toString());
// verticalMargin = 10.0;
// appBarHeight -= (_kAppBarHeight - Sizes.icon.appBar) / 2;
appBarHeight = 46.0; // 80.0 - 34.0
appBarItemsCrossAlignment = CrossAxisAlignment.end;
}
return ClipRRect(
borderRadius: BorderRadius.vertical(top: Radius.circular(35.0)),
child: BottomAppBar(
shape: CircularNotchedRectangle(),
notchMargin: _notchMargin,
child: Container(
height: appBarHeight,
margin: EdgeInsets.only(top: 34 / 2), // (vertical: verticalMargin),
child: Row(
// not really centered? Try adding a sizedBox below every item :D
crossAxisAlignment: appBarItemsCrossAlignment,
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: items,
),
),
color: _kBackgroundColor,
),
);
}
Widget _buildSpacingTabItem() {
return SizedBox(width: 24.0 * 2);
}
Widget _buildTabItem({
FABBottomAppBarItem item,
int index,
ValueChanged<int> onPressed,
}) {
bool selected = this.selectedIndex == index;
Color color = selected ? _kSelectedIconColor : _kIconColor;
return SizedBox(
height: _kIconShadowHeight,
width: _kIconShadowWidth,
child: InkWell(
customBorder: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(24.0),
),
onTap: () => onPressed(index),
child: Container(
decoration: null,
child: Icon(
item.iconName,
color: color,
size: 24.0,
),
),
),
);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment