I made a custom BottomNav Bar and wrapped it inside of a container so that I could give it some box shadow. But the box shadow does not apply. Here is the code
class CBottomNavBar extends StatefulWidget {
#override
_CBottomNavBarState createState() => _CBottomNavBarState();
}
class _CBottomNavBarState extends State<CBottomNavBar> {
#override
Widget build(BuildContext context) {
return Consumer<SManageIndex>(
builder: (context, manageIndex, child) => Container(
height: 80,
clipBehavior: Clip.hardEdge,
decoration: BoxDecoration(
color: primaryColorDark,
boxShadow: [
BoxShadow(color: primaryColorDark, blurRadius: 4, spreadRadius: 2)
],
borderRadius: BorderRadius.only(
topRight: Radius.circular(20), topLeft: Radius.circular(20))),
child: BottomNavigationBar(
backgroundColor: primaryColorDark,
items: [
BottomNavigationBarItem(
icon: Icon(
FontAwesomeIcons.hospital,
),
title: Text('Appointments')),
BottomNavigationBarItem(
icon: Icon(
FontAwesomeIcons.pills,
),
title: Text('Medicines'),
),
BottomNavigationBarItem(
icon: Icon(
FontAwesomeIcons.bookMedical,
),
title: Text('Documents'),
),
],
currentIndex: manageIndex.index,
onTap: (value) => manageIndex.changePage(value),
),
),
);
}
}
The thing is I want both the border radius and box shadow, so I am using a container. Any other straightforward ways of doing the same are also welcome.
Thank you for your time.
Your answer is Offset. Use Offset class in your decoration for boxShadow element, and you will be good do go
//dx is horiztonal and dy is vertical
// play with it
boxShadow: [BoxShadow(offset: Offset(dx, dy));
You need the Offset property of the BoxShadow,
The offset property is used to control the position of the shadow. It is zero by default so you'll need to add the Offset:
I added a demo using your widget tree as an example:
class CBottomNavBar extends StatefulWidget {
#override
_CBottomNavBarState createState() => _CBottomNavBarState();
}
class _CBottomNavBarState extends State<CBottomNavBar> {
#override
Widget build(BuildContext context) {
return Consumer<SManageIndex>(
builder: (context, manageIndex, child) => Container(
height: 80,
clipBehavior: Clip.hardEdge,
decoration: BoxDecoration(
color: primaryColorDark,
boxShadow: [
BoxShadow(
color: primaryColorDark, blurRadius: 4, spreadRadius: 2,
// add the offset property
offset: Offset(0, 5), // new line [move to the right[horizontally] by 0 ,move to the top[vertically] by 5]
),
],
borderRadius: BorderRadius.only(
topRight: Radius.circular(20), topLeft: Radius.circular(20))),
child: BottomNavigationBar(
backgroundColor: primaryColorDark,
items: [
BottomNavigationBarItem(
icon: Icon(
FontAwesomeIcons.hospital,
),
title: Text('Appointments')),
BottomNavigationBarItem(
icon: Icon(
FontAwesomeIcons.pills,
),
title: Text('Medicines'),
),
BottomNavigationBarItem(
icon: Icon(
FontAwesomeIcons.bookMedical,
),
title: Text('Documents'),
),
],
currentIndex: manageIndex.index,
onTap: (value) => manageIndex.changePage(value),
),
),
);
}
}
Related
I want circular borders on the top left and right in my navigation bar. below I have mentioned my bottom navigation bar code. how can I DO THAT? Appreciate your help on this. ............... ......................................... ..........................
import 'package:deltamax_health/Screens/welcome_screen.dart';
import 'package:flutter/material.dart';
import '../Constant/colors.dart';
import 'dashboard.dart';
class BottomNavigation extends StatefulWidget {
const BottomNavigation({ Key? key }) : super(key: key);
#override
State<BottomNavigation> createState() => _BottomNavigationState();
}
class _BottomNavigationState extends State<BottomNavigation> {
int _selectedindex = 0;
void _navigatePages(int index) {
setState(() {
_selectedindex = index;
});
}
final List<Widget> _Pages = [const Dashboard() ,const WelcomeScreen()];
#override
Widget build(BuildContext context) {
return Scaffold(
body: _Pages[_selectedindex],
bottomNavigationBar: BottomNavigationBar(
backgroundColor: Color.fromRGBO(115, 131, 163, 0.7490196078431373),
fixedColor: backgroundBlue,
currentIndex: _selectedindex,
onTap: _navigatePages,
type: BottomNavigationBarType.fixed,
items: const [
BottomNavigationBarItem(icon:Icon(
Icons.account_balance_wallet_outlined,
color: textblue,
size: 30,
), label: ""),
BottomNavigationBarItem(icon: Icon(
Icons.open_in_browser_outlined,
color: textblue,
size: 30,
), label: ""),
BottomNavigationBarItem(icon: Icon(
Icons.money_outlined,
color: textblue,
size: 30,
), label: "")
]),
);
}
}
Wrapping with Container and providing borderRadius seens solve the issue, but there will splash effect on corners. In this can use clipBehavior on Container.
bottomNavigationBar: Container(
clipBehavior: Clip.hardEdge, //or better look(and cost) using Clip.antiAlias,
decoration: BoxDecoration(
borderRadius: BorderRadius.only(
topRight: Radius.circular(24),
topLeft: Radius.circular(24),
),
),
child: BottomNavigationBar(
Or just use ClipRRect
body: _Pages[_selectedindex],
bottomNavigationBar: ClipRRect(
borderRadius: const BorderRadius.only(
topRight: Radius.circular(24),
topLeft: Radius.circular(24),
),
child: BottomNavigationBar(
Update 1
Use extendBody: true to extends the body to the bottom of the Scaffold. Or You can provide backgroundColor for simple case.
return Scaffold(
// backgroundColor: Colors.blue, //same as body color
extendBody: true,
body: _Pages[_selectedindex],
bottomNavigationBar:
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatefulWidget {
const MyApp({Key? key}) : super(key: key);
#override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> with TickerProviderStateMixin {
late TabController _tabController;
#override
void initState() {
super.initState();
_tabController = TabController(length: 4, vsync: this);
}
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
bottomNavigationBar: DefaultTabController(
length: 4,
initialIndex: 0,
child: Container(
margin: const EdgeInsets.only(bottom: .5),
padding: const EdgeInsets.only(top: 3),
height: 50,
decoration: BoxDecoration(
// color: Theme.of(context).backgroundColor,
color: Colors.white,
border: Border.all(
color: Colors.grey[700]!,
width: 0.5,
),
borderRadius: const BorderRadius.only(
topRight: Radius.circular(17),
topLeft: Radius.circular(17),
),
),
child: TabBar(
physics: const NeverScrollableScrollPhysics(),
isScrollable: false,
controller: _tabController,
indicatorWeight: 0,
// mouseCursor: MouseCursor.defer,
indicator: const UnderlineTabIndicator(
borderSide: BorderSide(
color: Colors.black,
width: 1,
),
// insets: EdgeInsets.symmetric(horizontal: 0),
),
tabs: [
kTabBarItemConstructor(
Icons.home,
'Home',
),
Container(
child: kTabBarItemConstructor(
Icons.home,
'Home',
),
),
Container(
child: kTabBarItemConstructor(
Icons.home,
'Profile',
),
),
// Tab(
// child: Container(
// child: Column(
// mainAxisAlignment: MainAxisAlignment.center,
// children: [
//
// Text(
// 'Корзина',
// style: TextStyle(
// fontSize: 9,
// color: Colors.grey[600],
// ),
// ),
// ],
// ),
// ),
// ),
kTabBarItemConstructor(
Icons.home,
'Profile',
),
],
),
),
),
));
}
}
Widget kTabBarItemConstructor(IconData icon, String text) {
return Tab(
child: Container(
height: 40,
width: 70,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(
icon,
color: Colors.black.withOpacity(.65),
size: 25,
),
Container(
// margin: EdgeInsets.symmetric(horizontal: 10),
child: Text(
text,
style: TextStyle(
fontSize: 9,
color: Colors.grey[600],
),
maxLines: 1,
overflow: TextOverflow.ellipsis,
),
),
],
),
),
);
}
Run on DartPad.
I created a custom bottom nave bar, but there is a white space still around it. How to get rid of it? also if I put a button inside a container in order to give it a height or width, the same issue will be found.
The Image Is:
The Code Is:
bottomNavigationBar: ClipRRect(
borderRadius: const BorderRadius.all(Radius.circular(40)),
// clipper: ,
child: Container(
clipBehavior: Clip.hardEdge,
margin: EdgeInsets.all(5.w),
decoration: BoxDecoration(
color: whiteColor,
borderRadius: const BorderRadius.all(Radius.circular(10)),
boxShadow: [
BoxShadow(
color: shadowColor.withOpacity(0.5),
spreadRadius: 5,
blurRadius: 7,
offset: const Offset(0, 3), // changes position of shadow
),
],
),
child: BottomNavigationBar(
currentIndex: pageIndex,
onTap: (int value) {
pageIndex = value;
setState(() {});
},
type: BottomNavigationBarType.fixed,
items: [
BottomNavigationBarItem(
icon: Icon(Icons.home),
label: 'home'.tr,
),
BottomNavigationBarItem(
icon: Icon(Icons.flag_sharp),
label: "add_opportunity".tr,
),
BottomNavigationBarItem(
icon: Icon(Icons.person),
label: 'profile'.tr,
),
],
),
),
),
Try extendBody:
return Scaffold(
extendBody: true,
bottomNavigationBar: ClipRRect(
borderRadius: const BorderRadius.all(Radius.circular(40)),
I want to show a bottom sheet when clicking on the floating button on the page. Page also includes bottom navigation bar. When clicking on the floating button, the bottom sheet appears above the navigation bar not on the bottom of the page. How can I achieve this?.
Code:
void main() {
runApp(App());
}
class App extends StatelessWidget {
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'app',
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: AppNavigation(),
);
}
}
class AppNavigation extends StatefulWidget {
#override
_AppNavigationState createState() => _AppNavigationState();
}
class _AppNavigationState extends State<AppNavigation> {
int _currentIndex = 0;
final List<Widget> _children = [
HomeScreen(),
SettingsScreen(),
];
void onTappedBar(int index) {
setState(() {
_currentIndex = index;
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: _children[_currentIndex],
bottomNavigationBar: BottomNavigationBar(
onTap: onTappedBar,
currentIndex: _currentIndex,
items: <BottomNavigationBarItem>[
BottomNavigationBarItem(
icon: Icon(Icons.home), title: Text('Home')),
BottomNavigationBarItem(
icon: Icon(Icons.settings), title: Text('Settings')),
]),
);
}
}
class HomeScreen extends StatelessWidget {
#override
Widget build(BuildContext context) {
var size = MediaQuery.of(context).size; // gives device width and height
return Scaffold(
floatingActionButton: FloatingActionButton(
onPressed: () {
showBottomSheet(
context: context,
builder: (context) => Container(
height: 320,
decoration: BoxDecoration(
boxShadow: [
BoxShadow(
color: Colors.grey.withOpacity(0.5),
spreadRadius: 5,
blurRadius: 20,
offset: Offset(0, 3),
),
],
color: Colors.white,
borderRadius: BorderRadius.only(
topLeft: Radius.circular(25),
topRight: Radius.circular(25),
),
),
padding:
EdgeInsets.symmetric(horizontal: 20, vertical: 30),
child: Center(child: Text('Bottom action sheet')),
));
},
child: Icon(Icons.add),
backgroundColor: Colors.deepPurple),
body: Center(child: Text("home page")));
}
}
Below is the output of above code.The bottom action sheet appears above the bottom navigation bar. I expect the bottom action should be on bottom of the screen.
I believe what you are trying to achieve is done by using "showModalBottomSheet" like this:
return Scaffold(
resizeToAvoidBottomInset: false,
floatingActionButton: FloatingActionButton(
onPressed: () {
// what you asked for
showModalBottomSheet(
barrierColor: Colors.white.withOpacity(0),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.vertical(
top: Radius.circular(25),
),
),
context: context,
builder: (context) => Container(
height: 320,
decoration: BoxDecoration(
boxShadow: [
BoxShadow(
color: Colors.grey.withOpacity(0.5),
spreadRadius: 5,
blurRadius: 20,
offset: Offset(0, 3),
),
],
color: Colors.white,
borderRadius: BorderRadius.only(
topLeft: Radius.circular(25),
topRight: Radius.circular(25),
),
),
padding:
EdgeInsets.symmetric(horizontal: 20, vertical: 30),
child: Center(child: Text('Bottom action sheet')),
));
},
child: Icon(Icons.add),
backgroundColor: Colors.deepPurple),
body: Center(child: Text("home page")));
edit: I have modified the code so that it has the same shadow effect like the one in the picture you've posted
I'm trying to give some rounded corners to my bottom navbar. For that, I have to make the background of its container transparent but I don't know how.
This is what I did int the Scaffold:
bottomNavigationBar: ClipRRect(
borderRadius: BorderRadius.only(topLeft: Radius.circular(30.0), topRight: Radius.circular(30.0), ),
child:BottomNavigationBar(
//elevation: 0.0,
type: BottomNavigationBarType.fixed,
backgroundColor: Colors.white10,
and the result :
There is still by default a white background. I tried to wrap my ClipRRect in a container with a transparent background but it did not work.
Any idea ?
need a little bit shadow like
bottomNavigationBar: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.only(
topRight: Radius.circular(30), topLeft: Radius.circular(30)),
boxShadow: [
BoxShadow(color: Colors.black38, spreadRadius: 0, blurRadius: 10),
],
),
child: ClipRRect(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(30.0),
topRight: Radius.circular(30.0),
),
child: BottomNavigationBar(
items: <BottomNavigationBarItem>[
BottomNavigationBarItem(
icon: Icon(Icons.favorite), title: Text('Favourite')),
BottomNavigationBarItem(
icon: Icon(Icons.favorite), title: Text('Favourite'))
],
),
)
)
without shadow :
with shadow :
Inside Scaffold, set extendBody property to true. This lets body extends to the bottom of the Scaffold, instead of only extending to the top of the bottomNavigationBar.
This should fix your problem.
Example:
Widget build(BuildContext context) {
return Scaffold(
body: bodyOfApp(),
extendBody: true,
backgroundColor: Colors.transparent,
bottomNavigationBar: BottomNavBar(),
);
}
All the above answers use ClipRRect in some way which is very costly computation-wise. Thus, as an alternative use Material Widget, here's how:
bottomNavigationBar: Container(
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.only(
topRight: Radius.circular(30), topLeft: Radius.circular(30)),
),
child: Material(
elevation: 0.0,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(30.0)),
child: BottomNavigationBar(
elevation: 0,
backgroundColor: Colors.transparent,
items: <BottomNavigationBarItem>[
BottomNavigationBarItem(
icon: Icon(Icons.favorite), title: Text('Favourite')),
BottomNavigationBarItem(
icon: Icon(Icons.favorite), title: Text('Favourite'))
],
),
)),
)
Change the canvasColor in your Theme to transparent.
return MaterialApp(
theme: ThemeData(
canvasColor: Colors.transparent
),
);
class _DashBoardActivityState extends State<DashBoardActivity> {
int _selectedIndex = 0;
static const TextStyle optionStyle =
TextStyle(fontSize: 30, fontWeight: FontWeight.bold);
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text("BottomNavigationBar"),
backgroundColor: PrimaryColor,),
body: Container(child: Center(child: _widgetOptions.elementAt(_selectedIndex),),),
bottomNavigationBar: CreateBottombar(context),
);
}
final _widgetOptions = [
new ListFragScreen(),
new ConsultationFragScreen(),
new LabFragScreen(),
];
void _onItemTapped(int index) {
setState(() {
_selectedIndex = index;
});
}
Container CreateBottombar(BuildContext context) {
return Container(
//add ClipRRect widget for Round Corner
child: ClipRRect(
borderRadius: const BorderRadius.only(
topRight: Radius.circular(24),
topLeft: Radius.circular(24),
),
child: BottomNavigationBar(
//add background color
backgroundColor: PrimaryColor,
items: const <BottomNavigationBarItem>[
BottomNavigationBarItem(
icon: Icon(Icons.home),
label: 'Home',
),
BottomNavigationBarItem(
icon: Icon(Icons.business),
label: 'Business',
),
BottomNavigationBarItem(
icon: Icon(Icons.school),
label: 'School',
),
],
currentIndex: _selectedIndex,
selectedItemColor: Colors.white,
onTap: _onItemTapped,
),
),
);
}
}
The method suggested by #CoderMonk should work. If it doesn't then I think you might be using something like SafeArea() widget in the body of your Scaffold(), If so you should either remove it completely or do something like
Scaffold(
body: SafeArea(
bottom: false,
child: ...
),
);
The solution with extendBody that helps to remove the background of the bar:
#override
Widget build(BuildContext context) {
return Scaffold(
extendBody: true, // Important: to remove background of bottom navigation (making the bar transparent doesn't help)
bottomNavigationBar: Container(
decoration: const BoxDecoration(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(12.0), // adjust to your liking
topRight: Radius.circular(12.0), // adjust to your liking
),
color: your_bar_color, // put the color here
),
child: BottomNavigationBar(backgroundColor: Colors.transparent), // don't forget to put it
),
body: SingleChildScrollView(
child: Column(
children: [
// widget
// widget
const SizedBox(height: kBottomNavigationBarHeight) // add space at the bottom due to extendBody property for proper scrolling
],
),
),
);
}
I want to set the borderRadius to an Bottom Navigation App Bar as its shown in the image. I have tried to put Bottom Navigation App Bar to a ClipRRect borderRadius and in a Container decoration but it didn't worked. So how can I apply the topLeft, and topRight border radius to my bottom navigation bar. Kindly help to let me know how can I do it?
main.dart
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Food Ordering',
theme: ThemeData(primarySwatch: Colors.blue, primaryColor: Colors.white),
home: MyStatefulWidget(),
routes: <String, WidgetBuilder>{
'/detail-page': (BuildContext context) => MyDetailPage(),
},
);
}
}
class MyStatefulWidget extends StatefulWidget {
MyStatefulWidget({Key key}) : super(key: key);
#override
_MyStatefulWidgetState createState() => _MyStatefulWidgetState();
}
class _MyStatefulWidgetState extends State<MyStatefulWidget> {
int _selectedIndex = 0;
static const TextStyle optionStyle =
TextStyle(fontSize: 30, fontWeight: FontWeight.bold);
static List<Widget> _widgetOptions = <Widget>[
HomePage(),
HomePage(),
HomePage(),
HomePage(),
];
void _onItemTapped(int index) {
setState(() {
_selectedIndex = index;
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
child: _widgetOptions.elementAt(_selectedIndex),
),
bottomNavigationBar: BottomNavigationBar(
items: <BottomNavigationBarItem>[
BottomNavigationBarItem(
icon: Image.asset('assets/icon-home.png'),
title: Text('Home'),
),
BottomNavigationBarItem(
icon: Image.asset('assets/icon-mentors.png'),
title: Text('Mentors'),
),
BottomNavigationBarItem(
icon: Image.asset('assets/icon-messages.png'),
title: Text('Messages'),
),
BottomNavigationBarItem(
icon: Image.asset('assets/icon-settings.png'),
title: Text('Settings'),
),
],
currentIndex: _selectedIndex,
selectedItemColor: Colors.blue,
onTap: _onItemTapped),
);
}
}
EDIT
Scaffold now has a property called extendBody which can be used to extend the body below a bottomBar. From the documentation,
If true, and bottomNavigationBar or persistentFooterButtons is specified, then the body extends to the bottom of the Scaffold, instead of only extending to the top of the bottomNavigationBar or the persistentFooterButtons.
This means that all you need to do is
class HomePage extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Some Text'),
),
body: bodyContent,
extendBody: true,
bottomNavigationBar: bottomNavigationBar,
);
}
Widget get bodyContent {
return Container(color: Colors.red);
}
Widget get bottomNavigationBar {
return ClipRRect(
borderRadius: const BorderRadius.only(
topRight: Radius.circular(40),
topLeft: Radius.circular(40),
),
child: BottomNavigationBar(
items: const [
BottomNavigationBarItem(icon: Icon(Icons.home), label: '1'),
BottomNavigationBarItem(icon: Icon(Icons.usb), label: '2'),
BottomNavigationBarItem(
icon: Icon(Icons.assignment_ind), label: '3'),
BottomNavigationBarItem(
icon: Icon(Icons.multiline_chart), label: '4'),
],
unselectedItemColor: Colors.grey,
selectedItemColor: Colors.black,
showUnselectedLabels: true,
),
);
}
}
OUTDATED
Put it inside a stack. Don't add the Bottom Navigation Bar to the scaffold directly.
class HomePage extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Some Text'),
),
body: Stack(
children: <Widget>[
bodyContent,
Positioned(
left: 0,
right: 0,
bottom: 0,
child: bottomNavigationBar,
),
],
),
);
}
Widget get bodyContent {
return Container(color: Colors.red);
}
Widget get bottomNavigationBar {
return ClipRRect(
borderRadius: BorderRadius.only(
topRight: Radius.circular(40),
topLeft: Radius.circular(40),
),
child: BottomNavigationBar(
items: [
BottomNavigationBarItem(icon: Icon(Icons.home), title: Text('1')),
BottomNavigationBarItem(icon: Icon(Icons.usb), title: Text('2')),
BottomNavigationBarItem(
icon: Icon(Icons.assignment_ind), title: Text('3')),
BottomNavigationBarItem(
icon: Icon(Icons.multiline_chart), title: Text('4')),
],
unselectedItemColor: Colors.grey,
selectedItemColor: Colors.black,
showUnselectedLabels: true,
),
);
}
}
Alternatively, if your goal is to only put a borderRadius you can just use ClipRRect and apply your desired borderRadius to it.
Here is my implementation of the solution:
ClipRRect _getBtmNavBar() {
return ClipRRect(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(25),
topRight: Radius.circular(25),
),
child: BottomNavigationBar(
currentIndex: _selectedIndex,
onTap: _onTabTapped,
selectedLabelStyle: TextStyle(
color: Colors.black87,
fontSize: 16,
),
iconSize: 35,
selectedItemColor: Colors.white,
unselectedItemColor: Colors.black54,
items: <BottomNavigationBarItem>[
BottomNavigationBarItem(
backgroundColor: kBottomNavBarBgColor,
icon: Icon(Icons.home),
title: Text('Home'),
),
// more BottomNavigationBarItem() goes here.
Then plug it directly into your bottomNavigationBar
Code Example:
return Scaffold(
// more Scaffold code goes here
//bottom navigationBar
bottomNavigationBar: _getBtmNavBar(),
);
You may user bellow like .
My bottomNavigationBar image is look like
2. here is thecode
import 'package:flutter/material.dart';
class BottomTab extends StatefulWidget {
#override
State<StatefulWidget> createState() {
return _BottomTab();
}
}
class _BottomTab extends State<BottomTab> {
int _selectedTabIndex = 0;
List _pages = [
Text("Home"),
Text("Order"),
Text("Notfication"),
Text("More"),
];
_changeIndex(int index) {
setState(() {
_selectedTabIndex = index;
print("index..." + index.toString());
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('bottom nav bar'),
),
body: Center(child: _pages[_selectedTabIndex]),
bottomNavigationBar: bottomNavigationBar,
);
}
Widget get bottomNavigationBar {
return Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.only(
topRight: Radius.circular(30), topLeft: Radius.circular(30)),
boxShadow: [
BoxShadow(color: Colors.black38, spreadRadius: 0, blurRadius: 10),
],
),
child: ClipRRect(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(30.0),
topRight: Radius.circular(30.0),
),
child: BottomNavigationBar(
currentIndex: _selectedTabIndex,
onTap: _changeIndex,
type: BottomNavigationBarType.fixed,
selectedFontSize: 12,
unselectedFontSize: 12,
selectedItemColor: Colors.amber[800],
unselectedItemColor: Colors.grey[500],
showUnselectedLabels: true,
items: <BottomNavigationBarItem>[
BottomNavigationBarItem(
icon: new Icon(Icons.home),
title: new Text('Home'),
),
BottomNavigationBarItem(
icon: new Icon(Icons.shopping_cart_outlined),
title: new Text('Order'),
),
BottomNavigationBarItem(
icon: new Icon(Icons.mail),
title: new Text('Messages'),
),
BottomNavigationBarItem(
icon: Icon(Icons.more_horiz_rounded), title: Text('More')),
],
),
));
}
}
Just include the BottomNavigationBar inside the body, inside a circular border container. Like this (See the picture attached!)
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: Container(
decoration: BoxDecoration(
image: DecorationImage(
image: new AssetImage("assets/images/background.jpg"),
fit: BoxFit.cover)),
child: Stack(
alignment: Alignment.bottomCenter,
children: <Widget>[
Expanded(
child: Column(
children: <Widget>[
Expanded(child: _children[_currentIndex]),
],
),
),
Container(
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.only(
topLeft: Radius.circular(20),
topRight: Radius.circular(20),
bottomLeft: Radius.circular(0),
bottomRight: Radius.circular(0)),
boxShadow: [
BoxShadow(
offset: Offset(0.0, 1.00), //(x,y)
blurRadius: 4.00,
color: Colors.grey,
spreadRadius: 1.00),
],
),
height: 70,
child: ClipRRect(
clipBehavior: Clip.hardEdge,
borderRadius: BorderRadius.only(
topLeft: Radius.circular(25),
topRight: Radius.circular(25),
bottomLeft: Radius.circular(0),
bottomRight: Radius.circular(0)),
child: Container(
child: BottomNavigationBar(
backgroundColor: Color.fromRGBO(255, 255, 255, 50),
showSelectedLabels: false,
showUnselectedLabels: false,
onTap: onTabTapped,
// new
currentIndex: _currentIndex,
// new
items: [
new BottomNavigationBarItem(
icon: Icon(
Icons.phone,
size: 30,
),
title: Text('Calls'),
),
new BottomNavigationBarItem(
icon: Icon(
Icons.mail,
size: 30,
),
title: Text('Messages'),
),
new BottomNavigationBarItem(
icon: Icon(
Icons.person,
size: 30,
),
title: Text('Profile'))
],
),
)),
)
],
)),
));
}