How to get gradient bottom navigation tab in flutter? - flutter

There is a package on pub
https://pub.dev/packages/gradient_bottom_navigation_bar
but this is not updated for a very long time.
So, is there a way to create own custom navigation bar with a gradient effect?
something like this...

All it's possible with Flutter, one option could be use a transparent background in your BottomNavigationBar and put it inside a container with a BoxDecoration, try the next:
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: Center(
child: Text("Hello"),
),
bottomNavigationBar: _createBottomNavigationBar(),
),
);
}
Widget _createBottomNavigationBar() {
return Container(
decoration: BoxDecoration(
gradient: LinearGradient(
colors: [Color(0xFF00D0E1), Color(0xFF00B3FA)],
begin: Alignment.topLeft,
end: Alignment.topRight,
stops: [0.0, 0.8],
tileMode: TileMode.clamp,
),
),
child: BottomNavigationBar(
currentIndex: 0,
onTap: (index) {},
showUnselectedLabels: false,
backgroundColor: Colors.transparent,
type: BottomNavigationBarType.fixed,
elevation: 0,
unselectedItemColor: Colors.white,
selectedIconTheme: IconThemeData(color: Colors.white),
items: [
BottomNavigationBarItem(
icon: Icon(Icons.home),
title: Text(
"Home",
style: TextStyle(color: Colors.white),
),
),
BottomNavigationBarItem(
icon: Icon(Icons.business),
title: Text(
"Business",
style: TextStyle(color: Colors.white),
),
),
BottomNavigationBarItem(
icon: Icon(Icons.school),
title: Text(
"School",
style: TextStyle(color: Colors.white),
),
),
],
),
);
}
}

I've got a more basic solution. You can check this DartPad.
The end result:
The trick is this:
Set the background color of BottomNavigationBar as transparent.
Wrap it with Stack.
Add a Container as first child to the Stack.
Set Container's decoration to gradient.
Set its height to 60.

Related

Persisting BottomNavigationBar with changing AppBar

So I'm creating an screen with 5 BottomNavigationBarItem(s) that would ideally persist, while the AppBar changes according to the design. Here's my code:
class ExploreState extends State<ExploreScreen> {
int _selectedIndexForBottomNavigationBar = 0;
void _onItemTappedForBottomNavigationBar(int index) {
setState(() {
_selectedIndexForBottomNavigationBar = index;
});
}
#override
Widget build(BuildContext context) {
return new DefaultTabController(
length: 3,
child: new Scaffold(
appBar: AppBar(
bottom: ColoredTabBar(
color: Colors.white,
tabBar: TabBar(
labelColor: Colors.grey[900],
indicator: UnderlineTabIndicator(
borderSide: BorderSide(color: kPrimaryColor, width: 2.0),
),
tabs: <Widget>[
Tab(text: "Job Posts"),
Tab(
text: "Agencies",
),
Tab(
text: "All Applicants",
),
],
),
),
elevation: 0.7,
centerTitle: true,
title: Text(
"Looking For",
style: TextStyle(fontSize: 18),
),
actions: <Widget>[
Icon(Icons.search),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 5.0),
),
],
),
body: TabBarView(
children: <Widget>[
Jobs(),
Agencies(),
Applicants(),
],
),
bottomNavigationBar: BottomNavigationBar(
type: BottomNavigationBarType.fixed,
items: <BottomNavigationBarItem>[
_bottomNavigationBarItem(
AssetImage("assets/images/search-job.png"), 'Explore'),
_bottomNavigationBarItem(
AssetImage("assets/images/message.png"), 'Messaging'),
_bottomNavigationBarItem(
AssetImage("assets/images/forums.png"), 'Forums'),
_bottomNavigationBarItem(
AssetImage("assets/images/notifications.png"), 'Notifications'),
_bottomNavigationBarItem(
AssetImage("assets/images/profile.png"), 'Edit Profile'),
],
currentIndex: _selectedIndexForBottomNavigationBar,
selectedItemColor: kPrimaryColor,
onTap: _onItemTappedForBottomNavigationBar,
selectedFontSize: 0,
),
),
);
}
BottomNavigationBarItem _bottomNavigationBarItem(
AssetImage icon, String label) {
return BottomNavigationBarItem(
activeIcon: _navItemIcon(
icon, label, [kPrimaryColor, kPrimaryWelcomeColor], Colors.white),
icon: _navItemIcon(
icon, label, [Colors.white, Colors.white], Color(0xFF4E5969)),
label: "",
);
}
Row _navItemIcon(AssetImage icon, String label, List<Color> backgrondColor,
Color? foregroundColor) {
return Row(
children: [
Expanded(
child: Container(
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.bottomLeft,
end: Alignment.topRight,
colors: backgrondColor,
transform: GradientRotation(1.5),
),
),
child: Padding(
padding: const EdgeInsets.all(15.0),
child: Column(
children: [
ImageIcon(
icon,
size: 25,
color: foregroundColor,
),
Text(
label,
style: TextStyle(color: foregroundColor, fontSize: 8),
)
],
),
),
),
),
],
);
}
}
class ColoredTabBar extends Container implements PreferredSizeWidget {
ColoredTabBar({this.color = Colors.white, this.tabBar});
final Color color;
final TabBar? tabBar;
#override
Size get preferredSize => tabBar!.preferredSize;
#override
Widget build(BuildContext context) => Container(
color: color,
child: tabBar,
);
}
Upon Login, they land on the 'Explore' screen but was wondering if this structure is ideal. What I was thinking was a 'common' scaffold for a blank body, 5 BottomNavigationBarItems and a changing AppBar Menu items (for instance, "Messaging" has "Conversations" and "Appointments" AppBar items)
How do we go about properly coding this.
Here is a Sample for the "Messaging" BottomNavigationBarItem.
One possible approach:
Create one Scaffold with your BottomNavigationBar.
Use an IndexedStack (see here) as the body of your Scaffold.
Create the different bodies (Explore, Messaging etc.) and use setState when user clicks on one of your BottomNavigationBarItems and change the current index for IndexedStack.
Also create different AppBar widgets for the different bodies (for example in an array), assign it to the Scaffold based on a state value and in the previously mentioned setState update also its value.
This will work until you can or want to keep all these widgets in the same Stateless Widget class. Chances are good that later you will want to separate them into different classes so that your code is more easy to read. In that case you can use ChangeNotifier, ChangeNotifierProvider and Consumer to communicate state changes between your widgets, as explained here.

How to apply elevation in bottom navigation bar in flutter?

I want to apply elevation in the bottom navigation bar. I tried elevation property but it doesn't work. Elevation property has a very negligible shadow effect. But according to my design I want higher elevation.
I want the following output...
'
import 'package:flutter/material.dart';
class HomePage extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Text('Sample App'),
),
bottomNavigationBar: BottomNavigationBar(
elevation: 10,
items: [
BottomNavigationBarItem(
icon: Icon(Icons.ac_unit),
title: Text('Test')
),
BottomNavigationBarItem(
icon: Icon(Icons.access_alarm),
title: Text('Test')
),
BottomNavigationBarItem(
icon: Icon(Icons.access_alarm),
title: Text('Test'),
),
],
),
);
}
}
I know it may not seem the best solution for this issue but you can wrap your Bottom Nav Bar inside a Container, and then apply a BoxDecoration on that.
class HomePage extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Text('Sample App'),
),
bottomNavigationBar: Container(
decoration: BoxDecoration(
boxShadow: <BoxShadow>[
BoxShadow(
color: Colors.black,
blurRadius: 10,
),
],
),
child: BottomNavigationBar(
elevation: 10,
items: [
BottomNavigationBarItem(
icon: Icon(Icons.ac_unit),
title: Text('Test'),
),
BottomNavigationBarItem(
icon: Icon(Icons.access_alarm),
title: Text('Test'),
),
BottomNavigationBarItem(
icon: Icon(Icons.access_alarm),
title: Text('Test'),
),
],
),
),
);
}
}
I hope someone come with a better solution for this issue.
I'm pretty late, but I got the perfect answer.
You can use a BottomAppBar instead of the BottomNavigationBar
Ex :
import 'package:flutter/material.dart';
class HomePage extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Text('Sample App'),
),
bottomNavigationBar: BottomAppBar(
elevation: 10,
child: Row(children :[
BottomNavigationBarItem(
icon: Icon(Icons.ac_unit),
title: Text('Test')
),
BottomNavigationBarItem(
icon: Icon(Icons.access_alarm),
title: Text('Test')
),
BottomNavigationBarItem(
icon: Icon(Icons.access_alarm),
title: Text('Test'),
),
]),
),
);
}
}
happy fluttering ! :)
elevation property
If null, defaults to 8.0.
final double elevation

Flutter how to add margin or padding in BottomNavigationBar

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(),
),

Flutter add a black outline to top of BottomNavigationBar

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

BottomNavigationBar color incorrectly change

I've a bottomnavigation bar that has a color. When I clicked on the last button, the color change to white ...
The last button show some card i can swipe.
For that i use the code here : https://github.com/devefy/Flutter-Story-App-UI
i've tried to change return container() whith something else, but nothing was heplful.
here is my code
void _onItemTapped(int index) {
setState(() {
if (edifice != null) _selectedIndex = index;
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.unEdifice.vocable),
backgroundColor: color_edifices,
),
body: Center(
child: edifice == null
? CircularProgressIndicator()
: _selectedIndex == 5
? SingleChildScrollView(
child: Column(
children: <Widget>[
Stack(
children: <Widget>[
CardScrollWidget(currentPage),
Positioned.fill(
child: PageView.builder(
itemCount: edifice.commentaires.length,
controller: controller,
reverse: true,
itemBuilder: (context, index) {
return Container(
);
},
),
)
],
),
],
),
)
: _widgetOptions.elementAt(_selectedIndex),
),
bottomNavigationBar: BottomNavigationBar(
items: const <BottomNavigationBarItem>[
BottomNavigationBarItem(
backgroundColor: color_edifices,
icon: Icon(GaeoIcons.church, color: Colors.white),
title: Text('Edifice', style: buttonTextStyle),
),
BottomNavigationBarItem(
icon: Icon(GaeoIcons.location_on, color: Colors.white),
title: Text('Adresses', style: buttonTextStyle),
),
BottomNavigationBarItem(
icon: Icon(GaeoIcons.group, color: Colors.white),
title: Text('Responsables', style: buttonTextStyle),
),
BottomNavigationBarItem(
icon: Icon(GaeoIcons.truck, color: Colors.white),
title: Text('Distributions', style: buttonTextStyle),
),
BottomNavigationBarItem(
icon: Icon(GaeoIcons.group, color: Colors.white),
title: Text('Contacts', style: buttonTextStyle),
),
BottomNavigationBarItem(
icon: Icon(GaeoIcons.comment, color: Colors.white),
title: Text('Commentaires', style: buttonTextStyle),
),
],
currentIndex: _selectedIndex,
selectedItemColor: Colors.amber[800],
onTap: _onItemTapped,
),
);
}
}`
You can see what i mean with the pictures included
Thanks for your help
I have tried to simulate your case with Story App UI
please try to
1. add BottomNavigationBar 's backgroundColor
2. test with BottomNavigationBarType.fixed and fixedColor
also reference Flutter BottomNavigationBar Colors
code snippet
bottomNavigationBar: BottomNavigationBar(
backgroundColor: Colors.brown,
type: BottomNavigationBarType.fixed,
fixedColor: Colors.white,
items: const <BottomNavigationBarItem>[
BottomNavigationBarItem(
backgroundColor: Colors.white,
icon: Icon(Icons.access_time, color: Colors.white),
title: Text('Edifice', ),
),
BottomNavigationBarItem(
icon: Icon(Icons.access_alarm, color: Colors.white),
title: Text('Adresses', ),
),
],
)
Test result of Story App UI with BottomNavigationBar