How to perfectly align bottom navigation item with docked fab? - flutter

I am new in flutter. I am trying to create a main screen where there is bottom bar with floating action button(FAB). The fab is docked at the center of bottom app bar. Meanwhile, the bottom app bar has 4 bottom navigation items. Currently all the items are not perfectly aligned with each other. The search and notification icons are too close to the center. Is there a way i can arrange it to make it better and perfectly aligned? Please help. Thank you
Current ui:
The code:
import 'package:flutter/material.dart';
class Dashboard extends StatefulWidget {
_DashboardState createState() => _DashboardState();
}
class _DashboardState extends State<Dashboard> {
int _selectedPage = 0;
final _pageOptions = [
Home(),
Discover(),
Notifications(),
Messages(),
];
Widget build(BuildContext context) {
final _drawerNav = Drawer(
child: ListView(
padding: EdgeInsets.zero,
children: <Widget>[
DrawerHeader(
child: Text('Drawer Header'),
decoration: BoxDecoration(color: colorPrimary),
),
ListTile(
title: Text('Item 1'),
onTap: () {},
),
Divider(),
ListTile(
title: Text('Item 2'),
onTap: () {},
),
Divider(),
],
),
);
final _bottomNav = BottomAppBar(
shape: CircularNotchedRectangle(),
notchMargin: 6,
clipBehavior: Clip.antiAlias,
child: BottomNavigationBar(
selectedItemColor: colorPrimary,
unselectedItemColor: Colors.grey,
currentIndex: _selectedPage,
onTap: (int index) {
setState(() {
_selectedPage = index;
});
},
items: [
BottomNavigationBarItem(
icon: Icon(Icons.home), title: Container(height: 8.0)),
BottomNavigationBarItem(
icon: Icon(Icons.search), title: Container(height: 8.0)),
BottomNavigationBarItem(
icon: Icon(Icons.notifications), title: Container(height: 8.0)),
BottomNavigationBarItem(
icon: Icon(Icons.message), title: Container(height: 8.0)),
],
),
);
final _fab = FloatingActionButton(
child: Icon(Icons.add),
backgroundColor: colorPrimary,
onPressed: () {},
);
return Scaffold(
appBar: AppBar(
title: Text('Test'),
backgroundColor: colorPrimary,
),
drawer: _drawerNav,
body: _pageOptions[_selectedPage],
floatingActionButton: _fab,
bottomNavigationBar: _bottomNav,
floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,
);
}
}

I made a quick and dirty fix
I made the bottom navigation bar using row. Instead of using 4 children, I use 5. One of them is a dummy child
https://gist.github.com/hariangr/2739c25dda72edcbc18073b907ef057a

Try setting type in BottomNavigationBar to BottomNavigationBarType.fixed
The bottom navigation bar's type changes how its items are displayed. If not specified, then it's automatically set to BottomNavigationBarType.fixed when there are less than four items, and BottomNavigationBarType.shifting otherwise.
BottomNavigationBarType.fixed, the default when there are less than four items. The selected item is rendered with the selectedItemColor if it's non-null, otherwise the theme's ThemeData.primaryColor is used. If backgroundColor is null, The navigation bar's background color defaults to the Material background color, ThemeData.canvasColor (essentially opaque white).
BottomNavigationBarType.shifting, the default when there are four or more items. If selectedItemColor is null, all items are rendered in white. The navigation bar's background color is the same as the BottomNavigationBarItem.backgroundColor of the selected item. In this case it's assumed that each item will have a different background color and that background color will contrast well with white.

Related

Floating action button not moving up with snackbar flutter

I am struggling making a FAB move up when a snackbar is showing.
Here is my set up.
I have my main page with a bottom navigation bar with 3 items.
The first item is basically a widget with a ListView and a floating action button.
Once you click an item of the list view, you navigate to a details page. If you then delete the item from the details page, you come back to the main page.
A snackbar then appears as a result from deleting the item.
The problem I have is that the snack bar is not moving up and hides the FAB.
It assumes it has something to do with context, but I don't know how.
If I move the FAB to the main page, the FAB goes up but it then hides last item of the listview.
Page with list view and FAB:
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
centerTitle: true,
title: Text(
title,
style: Theme.of(context).textTheme.titleMedium,
),
),
body: WidgetWithListView(),
floatingActionButton: FloatingActionButton.extended(
onPressed: () {
//do something
},
label: Text('label'),
icon: const Icon(Icons.add),
));
}
Main page:
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(appBarTitle,
style: Theme.of(context)
.textTheme
.titleLarge!
.copyWith(fontWeight: FontWeight.bold)),
actions: <Widget>[
IconButton(
icon: const Icon(some icon),
tooltip: 'some tooltip',
onPressed: () {
//do something;
},
),
]),
body: Center(
child: getBody(_selectedIndex),
),
bottomNavigationBar: BottomNavigationBar(
items: <BottomNavigationBarItem>[
BottomNavigationBarItem(
icon: const Icon(someIcon),
label: 'a label'y,
),
BottomNavigationBarItem(
icon: const Icon(someIcon),
label: 'a label',
),
BottomNavigationBarItem(
icon: const Icon(someIcon),
label: 'a label',
),
],
currentIndex: _selectedIndex,
type: BottomNavigationBarType.fixed,
onTap: _onItemTapped,
),
);
}
Thanks.

Show Music Player On Bottom of Every View of flutter app

I am new to flutter and I need to know, how can I show the music player on every view of the flutter app. Can you please guide me to do that, as I am using the bottom sheet in a flutter, and seems like it's not fit my purpose.
Here I need to add only the bottom widget which showing the music playing.
One possibility would be to use a bottomNavigationBar in your global Scaffold.
And in your body, you will have to create a new navigation stack in order for the navigation to change only the body (not replacing the whole Scaffold).
It would look like this:
class MusicApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
bottomNavigationBar: PlayerBottomBar(), // this is where you put your player bar
body: Navigator(
onGenerateRoute: (settings) {
return MaterialPageRoute(
builder: (context) {
// todo return a screen... ,
},
settings: settings,
);
},
),
);
}
}
Try this one I have used in my music app. one of the most straightforward solutions is to wrap widgets in columns in the bottom bar of the app at the root level.
return Scaffold(
body: tabs[currentTabIndex],
backgroundColor: ColorConstants.kBackGround,
bottomNavigationBar: Column(
mainAxisSize: MainAxisSize.min,
children: [
Container(
margin: const EdgeInsets.all(10),
width: 100.w,
height: 60,
alignment: Alignment.center,
color: Colors.black38,
child: Text(
"Mini Player",
style: Theme.of(context).textTheme.headline3,
),
),
BottomNavigationBar(
currentIndex: currentTabIndex,
elevation: 0,
onTap: (currentIndex) => setState(() {
currentTabIndex = currentIndex;
}),
selectedLabelStyle: const TextStyle(color: Colors.white),
selectedItemColor: ColorConstants.kDarkFontColor,
backgroundColor: ColorConstants.kBackGround,
showSelectedLabels: false,
showUnselectedLabels: false,
items: const [
BottomNavigationBarItem(icon: Icon(Icons.home), label: ""),
BottomNavigationBarItem(icon: Icon(Icons.search), label: ""),
BottomNavigationBarItem(icon: Icon(Icons.library_books), label: "")
],
)
],
),
);
also you can checkout this video for the open and close mini player when the song start youtube

how can I achieve a bottom navigation bar with these features?

There are five navigation items in total and the widths are 154,153,154,153,154. I know it's kind of strange but the UI design is like this. As for this I guess I cannot use any Widget about navigator in the flutter lib.
Each item contains an icon and a text as usual but the distance between the two should be set exactly. I don't know if it can be set in flutter widget bottomNavigatorBar.
Commonly, the color of the icon, text and the background will change when selected.
What I have done: I created a widget and add it to the bottom of every pages. As you can imagine, when jumping to a new page, the navigation bar will re-render. That is not the same as we use in our mobile phones.
I have found some articles and blogs, but still can't solve my problem. Is there any reference?
You can use the below code and redirect this page into main.dart and can use test and icon also.
class nav extends StatefulWidget {
#override
_navState createState() => _navState();
}
class _navState extends State<nav> {
int tabIndex = 0;
List<Widget> listScreens;
#override
void initState() {
ScreenUtil.init(width: 375, height: 812);
super.initState();
listScreens = [
Home(),
Treatments(),
Request(),
Appointments(),
Menu(),
];
}
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: listScreens[tabIndex],
bottomNavigationBar: new Theme(
data: Theme.of(context).copyWith(
canvasColor: Color(0xFF320151),
primaryColor: Color(0xFF320151)),
child: BottomNavigationBar(
backgroundColor: Color(0xFF38095c),
selectedItemColor: Color(0xFFe34fd1),
unselectedItemColor: Color(0xFF510382),
currentIndex: tabIndex,
onTap: (int index) {
setState(() {
tabIndex = index;
});
},
items: [
BottomNavigationBarItem(
title: Text(""),
icon: Container(
width: 154, child: Center(child: Icon(AntDesign.home))),
),
BottomNavigationBarItem(
title: Text(""),
icon: Container(
width: 153,
child: Center(
child: Icon(MaterialCommunityIcons.medical_bag))),
),
BottomNavigationBarItem(
title: Text(""),
icon: Container(
width: 154,
child: Center(child: Icon(Fontisto.share_a))),
),
BottomNavigationBarItem(
title: Text(""),
icon: Container(
width: 153,
child: Center(child: Icon(AntDesign.calendar))),
),
BottomNavigationBarItem(
title: Text(""),
icon: Container(
width: 154,
child: Center(child: Icon(Ionicons.ios_person))),
),
]),
)),
);
}
}

how to show the drawer icon on bottom right in flutter?

I need to show the the total of 5 icons (4 bottom navigation icon + 1 menu drawer icon) in the bottom of the page. I am using BottomNavigationBarItem to show the four bottom navigation icons. In that i need to add the menu drawer icon. I can find answers for only bottom right and left. Kindly help to resolve this
class HomeScreen extends StatefulWidget{
final int indexvalue;
HomeScreen({Key key, #required this.indexvalue}) : super(key: key);
#override
State createState() {
return HomeScreenState();
}
}
class HomeScreenState extends State<HomeScreen> {
final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>();
int _selectedPage = 0;
final _pageOptions = [
Screen1(),
WebView1(),
Home(),
Leader(),
];
#override
Widget build(BuildContext context){
Size size = MediaQuery.of(context).size;
var val = widget.indexvalue;
print(widget.indexvalue);
return MaterialApp(
title: 'Home',
home: Scaffold(
key: _scaffoldKey,
appBar: AppBar(title: Text('Home'),),
body: _pageOptions[_selectedPage],
endDrawer: build_1(),
bottomNavigationBar: new Theme(
data: Theme.of(context).copyWith(
// sets the background color of the `BottomNavigationBar`
canvasColor: Colors.green,
// sets the active color of the `BottomNavigationBar` if `Brightness` is light
primaryColor: Colors.red,
textTheme: Theme
.of(context)
.textTheme
.copyWith(caption: new TextStyle(color: Colors.yellow))), // sets the inactive color of the `BottomNavigationBar`
child: new BottomNavigationBar(
showSelectedLabels: false, // <-- HERE
showUnselectedLabels: false,
currentIndex: _selectedPage,
onTap: (int index) {
setState(() {
_selectedPage = index;
});
},
items: [
BottomNavigationBarItem(icon: Icon(Icons.home), title: Text('Home')),
BottomNavigationBarItem(icon: Icon(Icons.photo_library), title: Text('photo_library')),
BottomNavigationBarItem(icon: Icon(Icons.book), title: Text('book')),
BottomNavigationBarItem(icon: Icon(Icons.notifications), title: Text('download')),
],
),
),
)
);
}
}
build_1(){
return SizedBox(
//width: size.width,
child: Drawer(
child: new ListView(
children: <Widget>[
new DrawerHeader(
child: new Text("Drawer Header"),
decoration: new BoxDecoration(
color: Colors.blue,
),
),
new Text("Item 1"),
new Text("Item 2"),
new Text("Item 3"),
new Text("Item 4"),
new Text("Item 5"),
new Text("Item 6"),
],
),
),
);
}
You can add another item in your bottomNavigationBar
BottomNavigationBarItem(icon: Icon(Icons.menu), title: Text('Menu'))
and check the index in onTap method and call _scaffoldKey.currentState.openDrawer(); to open the drawer
onTap: () {
int menuIndex = 4;//if you want it to be the last(bottom right)
if (index == menuIndex) {
_scaffoldKey.currentState.openDrawer();
}
else {
setState(() {
_selectedPage = index;
});
}
}
}
if you want to just add an icon everywhere in your screen to open your drawer just call
_scaffoldKey.currentState.openDrawer(); in onTap method
For exampe:
IconButton(
icon: Icon(Icons.menu),
color: Colors.white,
onPressed: () {
_scaffoldKey.currentState.openDrawer();
},)
If you are using in your Scaffold:
drawer: Drawer() use _scaffoldKey.currentState.openDrawer();
endDrawer: Drawer() use _scaffoldKey.currentState.openEndDrawer();

How can I have the BottomNavigationBar respond to navigation to a new page via AlertDialog?

I have a navigation_bar.dart file that handles changing to new pages within my app. Within it, I am using the bottomNavigationBar to build out four different pages based on what tab is currently selected like so:
class NavigationBar extends StatefulWidget {
#override
_NavigationBarState createState() => _NavigationBarState();
}
class _NavigationBarState extends State<NavigationBar> {
int _selectedIndex = 0;
final List<Widget> _pageOptions = <Widget>[
Page1(),
Page2(),
Page3(),
Page4(),
];
void _onItemTapped(int index) {
setState(() {
_selectedIndex = index;
});
}
#override
Widget build(BuildContext context) {
String userID =
Provider.of<FirebaseUser>(context, listen: false) != null ? Provider.of<FirebaseUser>(context).uid : 'null';
return MultiProvider(
providers: [StreamProvider<MyUser>.value(value: DatabaseService().streamUser(userID))],
child: Scaffold(
body: IndexedStack(
children: _pageOptions,
index: _selectedIndex,
),
bottomNavigationBar: Theme(
data: Theme.of(context).copyWith(
canvasColor: Color(0xff271037).withOpacity(0.90),
splashColor: Colors.transparent,
),
child: BottomNavigationBar(
currentIndex: _selectedIndex,
onTap: _onItemTapped,
unselectedItemColor: Colors.white,
selectedItemColor: Color(0xff3ADEA7),
type: BottomNavigationBarType.fixed,
items: <BottomNavigationBarItem>[
BottomNavigationBarItem(
icon: Container(),
title: Icon(FontAwesomeIcons.fire, color: Colors.white),
),
BottomNavigationBarItem(
icon: Container(),
title: Icon(Icons.fastfood, color: Colors.white),
),
BottomNavigationBarItem(
icon: Container(),
title: Icon(Icons.directions_bike, color: Colors.white),
),
BottomNavigationBarItem(
icon: Container(),
title: Icon(Icons.person, color: Colors.white),
)
],
),
),
),
);
}
}
Now, in a different file which is Page3.dart, on that page there is an alert dialog that pops up and when clicked, I want it to navigate to Page4().
Future<void> _showMissingDataDialog(String data) async {
return showDialog<void>(
context: context,
barrierDismissible: false,
builder: (BuildContext context) {
return AlertDialog(
title: Text('You have not set your $data yet.'),
actions: <Widget>[
FlatButton(
splashColor: Colors.transparent,
highlightColor: Colors.grey[200],
textColor: Colors.black,
child: const Text('Cancel'),
onPressed: () => Navigator.of(context).pop(),
),
FlatButton(
splashColor: Colors.transparent,
highlightColor: Colors.grey[200],
textColor: Colors.black,
child: Text('Set $data', style: TextStyle(fontWeight: FontWeight.bold)),
onPressed: () {
Navigator.of(context).pop();
// TODO: Redirect to page4() here as if it was tapped on the BottomNavigationBar
})
],
);
},
);
}
How can I have it so that clicking the "Set $data" button would route to Page4()? I want to make it so that the bottomNavigationBar reacts to this as if you tapped on the actual fourth BottomNavigationBarItem item.
Give your Nav Bar a Global Key. I declared this outside of all widgets on my main Dart file.
GlobalKey navBarGlobalKey = GlobalKey(debugLabel: 'bottomAppBar');
bottomNavigationBar: BottomNavigationBar(
key: navBarGlobalKey,
onTap: _onItemTapped,
currentIndex: _selectedIndex,
type: BottomNavigationBarType.fixed,
items: [ ... ]
Then use the global key to call the onTap Method in the onPressed method of your button. You will have to import the other dart file into this page before the global key is available.
final BottomNavigationBar navigationBar = navBarGlobalKey.currentWidget;
initialIndex = 0;
navigationBar.onTap(3); //Starts at index 0, so passing in 3 should do the trick.