I am trying to figure out how to add a very subtle black line to the top of a BottomNavigationBar to make it's start more distinct from the rest of the content. AirBnb would be a good example of this.
Is there a way to achieve this with Flutter?
Below is the widget I am currently using to render the BottomNavigationBar and I have attached a sample below where there is a distinct grey line at the top of the navbar for AirBnb.
#override
Widget build(BuildContext context) {
return Scaffold(
body: currentPage,
bottomNavigationBar: PreferredSize(
preferredSize: Size.fromHeight(50),
child: Container (
decoration: BoxDecoration(
border: Border.all(color: Colors.black)
),
)
),
);
}
The parent of this Widget:
void main() => runApp(MaterialApp(
home: new MyApp(),
debugShowCheckedModeBanner: true,
));
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Navbar();
}
}
How to add line on top of bottom navigation view in flutter ?
Code
class BottomNavigationBarHandler {
Widget bar(int currentIndex) {
return Container(
decoration: BoxDecoration(
color: Colors.white,
border: Border(top: BorderSide(color: Colors.white, width: 3.0))),
child: BottomNavigationBar(
backgroundColor: Colors.black,
selectedItemColor: Colors.pinkAccent,
unselectedItemColor: Colors.white,
showSelectedLabels: false,
showUnselectedLabels: false,
onTap: onTabTapped,
currentIndex: currentIndex,
items: [
BottomNavigationBarItem(
icon: Icon(Icons.home_outlined),
title: Text('Home')),
BottomNavigationBarItem(
icon: Icon(Icons.search),
title: Text('Messages')),
BottomNavigationBarItem(
icon: Icon(Icons.add),
title: Text('Profile'))]));
}
void onTabTapped(int index) {
print('BottomNavigationBarIndex ::' + index.toString());
}
}
Output
Widget build(BuildContext context) {
return Scaffold(
appBar: PreferredSize(
preferredSize: Size.fromHeight(200),
child: Container(
alignment: Alignment.center,
color: globals.white,
height: 100,
child: Text('imyadunandan'),
),
),
body: Container(
color: globals.white,
),
bottomNavigationBar: Container(
decoration: BoxDecoration(
color: globals.white,
boxShadow: [
BoxShadow(
color: globals.black,
),
],
),
child: BottomNavigationBar(
items: [
BottomNavigationBarItem(
icon: Icon(Icons.android),
title: Text('Android'),
),
BottomNavigationBarItem(
icon: Icon(Icons.desktop_windows),
title: Text('Windows'),
),
],
backgroundColor: globals.white,
elevation: 0,
),
),
);
}
this code achieves the fallowing
Related
class HomeView extends GetView<HomeController> {
#override
final HomeController controller = Get.put(HomeController());
buildNavBar() {
return Obx(
() => BottomAppBar(
shape: const CircularNotchedRectangle(),
color: MyColorStyle.primary,
notchMargin: 4,
clipBehavior: Clip.antiAlias,
child: BottomNavigationBar(
type: BottomNavigationBarType.fixed,
iconSize: 30.0,
showSelectedLabels: false,
showUnselectedLabels: false,
selectedItemColor: MyColorStyle.primary,
unselectedItemColor: Colors.grey[600],
onTap: controller.changeTabIndex,
currentIndex: controller.tabIndex.value,
backgroundColor: Colors.white,
items: const [
BottomNavigationBarItem(icon: Icon(Icons.dashboard), label: ''),
BottomNavigationBarItem(
icon: Icon(Icons.calendar_today), label: ''),
BottomNavigationBarItem(icon: Icon(Icons.show_chart), label: ''),
BottomNavigationBarItem(icon: Icon(Icons.settings), label: ''),
],
),
),
);
}
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
extendBody: true,
floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,
floatingActionButton: FloatingActionButton(
backgroundColor: MyColorStyle.primary,
elevation: 2,
onPressed: () {
showModalBottomSheet(
isScrollControlled: true,
context: context,
builder: (BuildContext context) => ClipRRect(
borderRadius: const BorderRadius.only(
topLeft: Radius.circular(40), topRight: Radius.circular(40)),
child: SizedBox(
height: Get.height * 0.8,
child: Container(),
),
),
);
},
child: const Icon(Icons.add),
),
bottomNavigationBar: buildNavBar(),
body: Obx(
() => IndexedStack(
index: controller.tabIndex.value,
children: [
SizedBox(),
SizedBox(),
SizedBox(),
SizedBox(),
],
),
),
);
}
}
image here(blue space)
I tried solving it with SafeArea. I can't remove the space at the bottom. None of the methods have achieved the solution I wanted.
When I made a BottomNavBar like this a while ago, there was no auto-space for the home indicator. For this, I couldn't reach a property in Scaffold or anywhere else.
That is the gesture system navigation bar, which depends on the user's phone settings. You cannot remove but you can change the color. In the main method, before calling runApp(),
void main() {
WidgetsFlutterBinding.ensureInitialized();
SystemChrome.setSystemUIOverlayStyle(const SystemUiOverlayStyle(
systemNavigationBarColor: appWhite,
systemNavigationBarDividerColor: appWhite,
systemNavigationBarIconBrightness: Brightness.dark));
runApp(const App());
}
I couldn't remove the space at the bottom, but I wrapped my Scaffold with SafeArea. I made the color of the space the same as my page by wrapping the SafeArea in the Container and giving the Container a white color. Sayfamın başlangıcı bu şekilde oldu.
Widget build(BuildContext context) {
return Container(
color: Colors.white,
child: SafeArea(
child: Scaffold(
[![When I click on any card the navigation bar doesn't work anymore ][2]][2]
the 1st image shows my navigation bar which works very well. The moment I click on a card the navigation bar doesn't work anymore and I didn't find out what is the reason
**This is my navigation bar Widget code that I'm using after clicking on the card **
class MenuBarWidget extends StatefulWidget {
#override
_State createState() => _State();
}
class _State extends State<MenuBarWidget> {
int _index = 0;
#override
Widget build(BuildContext context) {
return Container(
height: 70,
decoration: BoxDecoration(
gradient: AppGradients.linear,
),
child: BottomNavigationBar(
onTap: (newIndex) => setState(() => _index = newIndex),
currentIndex: _index,
unselectedItemColor: Colors.white70,
selectedItemColor: Colors.white,
elevation: 0,
items: const <BottomNavigationBarItem>[
BottomNavigationBarItem(
icon: Icon(Icons.home_outlined),
label: 'Principal',
backgroundColor: Colors.transparent,
),
BottomNavigationBarItem(
icon: Icon(Icons.assignment_outlined),
label: 'Pedidos',
backgroundColor: Colors.transparent,
),
BottomNavigationBarItem(
icon: Icon(Icons.chat_outlined),
label: 'Chat',
backgroundColor: Colors.transparent,
),
BottomNavigationBarItem(
icon: Icon(Icons.person_outline),
label: 'Perfil',
backgroundColor: Colors.transparent,
),
],
),
);
}
}
this is my code after clicking on the card
#override
Widget build(BuildContext context) {
return Scaffold(
bottomNavigationBar: MenuBarWidget(),
appBar: PreferredSize(
preferredSize: Size.fromHeight(100),
child: Stack(children: [
Container(
height: 128,
decoration: BoxDecoration(
color: AppColors.green,
border: Border(
bottom: BorderSide(
color: AppColors.blueButton,
width: 2,
),
),
image: DecorationImage(
image: AssetImage(AppImages.dots),
fit: BoxFit.cover,
),
),
),
Align(
alignment: Alignment(-0.7, -0.3),
child: RichText(
text: TextSpan(
text: serviceName,
style: TextStyle(
color: AppColors.white,
fontSize: 25,
fontWeight: FontWeight.bold,
),
),
),
),
Align(
alignment: Alignment(-0.6, 0.4),
child: RichText(
text: TextSpan(
text: 'Confira abaixo todos os profissionais desta categoria',
style: TextStyle(
color: AppColors.white,
fontSize: 9,
fontWeight: FontWeight.bold,
),
),
),
),
]),
),
**Any help is appreciated thanks **
create a new list of screens and add the screens you created as the list items
List screens = [
HomeScreen();
CarpentryScreen();
...
...
];
then make the body of your MenuBarWidget() return screens[_index]
class MenuBarWidget extends StatefulWidget {
#override
_State createState() => _State();
}
class _State extends State<MenuBarWidget> {
int _index = 0;
// new list of your screens
List<Widget> screens = [
PrincipalScreen(),
PedidosScreen(),
Chatscreen(),
Perfilscreen(),
];
#override
Widget build(BuildContext context) {
// return the screens
return Scaffold(
body: screens[_index],
bottomNavigationBar: BottomNavigationBar(
onTap: (newIndex) => setState(() => _index = newIndex),
currentIndex: _index,
unselectedItemColor: Colors.white70,
selectedItemColor: Colors.white,
elevation: 0,
items: const <BottomNavigationBarItem>[
BottomNavigationBarItem(
icon: Icon(Icons.home_outlined),
label: 'Principal',
backgroundColor: Colors.transparent,
),
BottomNavigationBarItem(
icon: Icon(Icons.assignment_outlined),
label: 'Pedidos',
backgroundColor: Colors.transparent,
),
BottomNavigationBarItem(
icon: Icon(Icons.chat_outlined),
label: 'Chat',
backgroundColor: Colors.transparent,
),
BottomNavigationBarItem(
icon: Icon(Icons.person_outline),
label: 'Perfil',
backgroundColor: Colors.transparent,
),
],
),
);
}
}
then you don't have to add bottomNavigationBar to the screens individually, this way, the screen is persistent across all screens
enter image description here
I want to make this type of bottom navigation bar, can anyone help?
You can dock your FloatingActionButton using the floatingActionButtonLocation property of Scaffold.
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: Scaffold(
body: const Center(child: const Text('asdfasdfasdf')),
floatingActionButtonLocation: FloatingActionButtonLocation.endDocked,
floatingActionButton: Container(
margin: const EdgeInsets.only(right: 55),
decoration: BoxDecoration(
shape: BoxShape.circle,
border: Border.all(color: Colors.white, width: 5),
),
child: FloatingActionButton(
onPressed: () {},
elevation: 0,
backgroundColor: Colors.red,
child: const Icon(Icons.star_purple500_sharp),
),
),
bottomNavigationBar: BottomNavigationBar(
onTap: (int i) {},
backgroundColor: Colors.red,
currentIndex: 0,
type: BottomNavigationBarType.fixed,
items: <BottomNavigationBarItem>[
BottomNavigationBarItem(
icon: const Icon(Icons.headset_mic_rounded),
label: '',
),
BottomNavigationBarItem(
icon: const Icon(Icons.headset_mic_rounded),
label: '',
),
BottomNavigationBarItem(
icon: const Icon(Icons.headset_mic_rounded),
label: '',
),
BottomNavigationBarItem(
icon: const Icon(Icons.headset_mic_rounded),
label: '',
),
],
),
),
);
}
}
You can try curved_navigation_bar package in bottomNavigationBar.
I have extra footer BottomAppBar that I don't want to be there. I want the Bottom Navigation Bar to be nested within the Bottom App Bar because I still want to keep the notch for the Floating Action Button. The screenshot shows it clearly, as it is colored Red.
This is my code:
class _MyHomePageState extends State<MyHomePage> {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: PreferredSize(
preferredSize: Size.fromHeight(0),
child: AppBar(
elevation: 0,
backgroundColor: Colors.transparent.withOpacity(0.4),
),
),
extendBodyBehindAppBar: true,
body: Container(
width: double.infinity,
height: double.infinity,
color: Colors.blue,
),
bottomNavigationBar: bottomNavBar,
floatingActionButton: addPostButton,
floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,
);
}
Widget get bottomNavBar {
return BottomAppBar(
color: Colors.red,
shape: CircularNotchedRectangle(),
elevation: 0,
notchMargin: 10,
child: BottomNavigationBar(
elevation: 0,
items: [
BottomNavigationBarItem(
icon: Icon(MdiIcons.homeOutline),
activeIcon: Icon(MdiIcons.home),
title: Text("Home"),
),
BottomNavigationBarItem(
icon: Icon(MdiIcons.accountOutline),
activeIcon: Icon(MdiIcons.account),
title: Text("Profile"),
),
],
),
);
}
Widget get addPostButton {
return FloatingActionButton(
focusElevation: 0,
onPressed: () {},
child: Icon(
MdiIcons.mapMarkerPlusOutline,
size: 30,
),
);
}
}
Change your code as per below then check:
Widget get bottomNavBar {
return BottomNavigationBar(
elevation: 0,
items: [
BottomNavigationBarItem(
icon: Icon(MdiIcons.homeOutline),
activeIcon: Icon(MdiIcons.home),
title: Text("Home"),
),
BottomNavigationBarItem(
icon: Icon(MdiIcons.accountOutline),
activeIcon: Icon(MdiIcons.account),
title: Text("Profile"),
),
],
);
}
I am trying to make bottom navigation bar, but with padding left and right on the screen. Right now I wrap the BottomNavigationBar with container and add padding there. The problem is the BottomNavigationBar default background still wrap all the layer, so could we remove the background color there?
Goal
Current result
bottomNavigationBar: Container(
margin: EdgeInsets.only(left: 16, right: 16),
decoration: BoxDecoration(
color: Colors.black,
borderRadius: BorderRadius.only(
topLeft: Radius.circular(20),
topRight: Radius.circular(20)),
),
child: BottomNavigationBar(
backgroundColor: Colors.transparent,
showUnselectedLabels: true,
type: BottomNavigationBarType.fixed,
elevation: 0,
currentIndex: _currentIndex,
items: [
BottomNavigationBarItem(
icon: Icon(Icons.home), title: Text('Home')),
BottomNavigationBarItem(
icon: Icon(Icons.local_activity), title: Text('Activity')),
BottomNavigationBarItem(
icon: Icon(Icons.inbox), title: Text('Inbox')),
BottomNavigationBarItem(
icon: Icon(Icons.person), title: Text('Profile')),
],
),
),
Edit: I have removed background color in scaffold and all theme, but when you have scrolled item, you could see there is still background there
Remove Scafold bg
Edit 2: here the code for the activity
class App extends StatelessWidget {
final List<Widget> _children = [
Center(
child: Container(
height: 850,
color: Colors.red,
),
)
];
#override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
home: Scaffold(
body: _children[0],
bottomNavigationBar: Container(
margin: EdgeInsets.only(left: 16, right: 16),
decoration: BoxDecoration(
color: Colors.amber,
borderRadius: BorderRadius.only(
topLeft: Radius.circular(200), topRight: Radius.circular(200)),
),
child: BottomNavigationBar(
backgroundColor: Colors.transparent,
showUnselectedLabels: true,
type: BottomNavigationBarType.fixed,
elevation: 0,
items: [
BottomNavigationBarItem(
icon: Icon(Icons.home), title: Text('Home')),
BottomNavigationBarItem(
icon: Icon(Icons.local_activity), title: Text('Activity')),
BottomNavigationBarItem(
icon: Icon(Icons.inbox), title: Text('Inbox')),
BottomNavigationBarItem(
icon: Icon(Icons.person), title: Text('Profile')),
],
),
),
),
);
}
}
result
You need to put the Body and the BottomNavigationBar under a Stack so that the BottomNavigationBar can be placed on top of the main body content.
Your complete code will be:
import 'package:flutter/material.dart';
class App extends StatelessWidget {
#override
Widget build(BuildContext context) {
final List<Widget> _children = [
Center(
child: Container(
height: 850, // use 'MediaQuery.of(context).size.height' to fit the screen height,
color: Colors.red,
),
)
];
return MaterialApp(
debugShowCheckedModeBanner: false,
home: Scaffold(
body: Stack(
children: <Widget>[
_children[0],
Positioned(
left: 0,
right: 0,
bottom: 0,
child: bottomNavigationBar(),
),
],
),
));
}
}
Widget bottomNavigationBar() {
return Container(
margin: EdgeInsets.only(left: 16, right: 16),
decoration: BoxDecoration(
color: Colors.amber,
borderRadius: BorderRadius.only(
topLeft: Radius.circular(200), topRight: Radius.circular(200)),
),
child: BottomNavigationBar(
backgroundColor: Colors.transparent,
showUnselectedLabels: true,
type: BottomNavigationBarType.fixed,
elevation: 0,
items: [
BottomNavigationBarItem(icon: Icon(Icons.home), title: Text('Home')),
BottomNavigationBarItem(
icon: Icon(Icons.local_activity), title: Text('Activity')),
BottomNavigationBarItem(icon: Icon(Icons.inbox), title: Text('Inbox')),
BottomNavigationBarItem(
icon: Icon(Icons.person), title: Text('Profile')),
],
),
);
}
Partial code from:
How to set border radius to bottom app bar in a flutter app?
I know it's kinda late. But this should help future viewers like me.
The icon parameter from BottomNavigationBarItem takes in a Widget. What I did is to just wrap my Icon into a Container and defined a padding.
BottomNavigationBarItem(
icon: Container(
padding: EdgeInsets.symmetric(vertical: 10),
child: Icon(
Icons.home
)
)
)
For some one is looking for solution:
You can wrap BottomNatigationBar in a Container with padding/margin properties, set same background color an set elevation of BottomNavigationBar to 0.
eg:
Container(
color: Colors.white,
padding: EdgeInsets.symmetric(horizontal: 10),
child: BottomNavigationBar(
onTap: (index) {
controller.tabIndex.value = index;
},
backgroundColor: Colors.white,
elevation: 0,
...
}
If you came here searching for how to add a padding at the bottom of the BottomNavigationBar, here it is the solution:
Wrap the BottomNavigationBar with a MediaQuery and provide a bottom padding, this value is taken in consideration when build the bottom bar.
MediaQuery(
data: MediaQueryData(
padding: EdgeInsets.only(bottom: 10) // here is the padding
),
child: BottomNavigationBar(),
),