in flutter BottomNavigationBar not working - flutter

bottomNavigationBar: new BottomNavigationBar(items: [
new BottomNavigationBarItem(icon: new Icon(Icons.account_balance))]),
When I run, I get this error

As the error suggested it needs 2 or more items in bottom navigation bar. The idea is, if you have a navigation bar you should have multiple items to navigate. If you want only one item don't use BottomNavigationBar

You need to have at least 2 children for your items like:
bottomNavigationBar: BottomNavigationBar(
items: [
BottomNavigationBarItem(
icon: Icon(Icons.account_balance),
),
BottomNavigationBarItem(
icon: Icon(Icons.account_circle),
),
],
)

Related

What's the name of flutter widget that has icons bellow the screen?

What's the name of the Flutter widget that has icons below the screen and I can slide to right and left to change between these screens (Ex: Twitter main page)
I could create a Container with a Row and the Icons and do this manually, but I suspect that already exists this widget on Flutter.
this bottom navigation bar can be done using BottomNavigationBar in the bottomNavigationBar property on your Scaffold :
bottomNavigationBar: BottomNavigationBar(
items: [
BottomNavigationBarItem(icon: Icon(Icons.home), label: 'Home'),
BottomNavigationBarItem(
icon: Icon(Icons.business), label: 'Business'),
BottomNavigationBarItem(icon: Icon(Icons.school), label: 'School'),
],
),
and for the slidable pages can be done using a PageView widget:
PageView(
children: <Widget>[
ScreenOne(),
ScreenTwo(),
ScreenThree(),
],
);
and you can link both of them when you click an item in the BottomNavigationBar, it will navigate to a specific page with a PageController.

How to add Search Bar in persistent bottom navigation bar

I've to create bottom menu like above image. Is there any way to create bottom menu with search bar. the search bar view is static.
Help me creating view like this in flutter.
you can add the search field to the BottomNavigationBarItem icon parameter
bottomNavigationBar: BottomNavigationBar(
items: const <BottomNavigationBarItem>[
BottomNavigationBarItem(
icon: Icon(Icons.home),
label: 'Home',
),
BottomNavigationBarItem(
icon: Icon(Icons.car_crash),
label: 'Car',
),
BottomNavigationBarItem(icon: TextField(), label: "search")
],
)

BottomNavigationBar without loading all pages at once

I have a screen with a BottomNavigationBar and an IndexedStack that swaps the child view based on the bottom bar index.
Everything is ok, except that all four pages are created at once, loading their data that is quite heavy and slowing down the app for some seconds.
Is there a setup that allows me to load each page only when the corresponding tab gets tapped?
Condition1: You want to simply load all tabs under IndexStack() at once during start and preserve them.
Solution: Use 'const' in front of all tabs in IndexedStack() > children[].
Condition 2: You want to load only the Homepage and the rest of the pages on their respective index clicks.
Solution: In children[] under IndexdStack() provide ternary condition with option for empty containers for all tabs. Put ternary condition of currentIndex. In this case though, the respective tab will load each time you click on it.
Condition 3: You want to load only the Homepage and the rest of the pages on their respective index clicks and preserve them once loaded.
Solution:
Use the solution for condition 2
Set up a bool 'ex. pageLoaded'. One for each tab.
Call the bool in the IndexedStack() > OnTap. Make it true on respective index clicks.
Set up another ternary operation against the first ternary operation with 'const Tabname' as the alternative.
I would suggest to remove the IndexedStack and make the widgets List and render the data based on the index.
List<Widget> _pages = [Home(), Business(),School()];
Make the Provider/Bloc instance on your bottom navigation container widget
return MultiProvider(
providers [
Provider<Something>(create: (_) => Something()),
],
child :Scaffold(
appBar: AppBar(
title: const Text('BottomNavigationBar Sample'),
),
body: _pages[_selectedIndex],
bottomNavigationBar: BottomNavigationBar(
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.amber[800],
onTap: _onItemTapped,
)
)
On each page bind the consumer of the provider, call the api in your provider

How to prevent iphone notch from overlapping content in bookmarked desktop app?

I'm using SafeArea to display a bottom navigation bar :
SafeArea(
child: ScaffoldMessenger(
child: Scaffold(
body: _tabs[index],
bottomNavigationBar: BottomNavigationBar(
selectedItemColor: Theme.of(context).primaryColor,
unselectedItemColor: Colors.grey,
showUnselectedLabels: true,
items: [
BottomNavigationBarItem(
icon: Icon(Icons.calendar_today), label: "Agenda"),
BottomNavigationBarItem(
icon: Icon(Icons.people), label: "Patients"),
BottomNavigationBarItem(
icon: Icon(Icons.account_balance_wallet), label: "Comptes"),
BottomNavigationBarItem(
icon: Icon(Icons.settings), label: "Réglages"),
],
currentIndex: index,
onTap: (i) => context.read(navigationIndexProvider).index = i,
),
),
),
);
When bookmarked on iphone desktop, the safe area does not prevent the notch from overlapping the bottom navbar.
Here is the result :
How to properly prevent notch from overlapping the bottom bar ?
In SAFEAREA widget there is an argument -bottom
Set this bottom either true or false.
SafeArea(
bottom:true,
child:ScaffoldMessanger()
)
I don't remember the correct one, you can check both and let us know which one works for you.
I think since you're using bottomNavigationBar, the SafeArea should not be wrapped around Scaffold. It should be wrapped by Scaffold like this:
Scaffold(
body: SafeArea(child:
_tabs[index] ...
I think you should only wrap Scaffold with SafeArea when you're not using any kind of bottomNavigationBar

How to make Ink effect fill all the space in a BottomNavigationBarItem

I'm making a simple Flutter app with a BottomNavigationBar and the label in my BottomNavigationBarItem exceeds the ink effect created when I tap on it . For some reason, it seems to be covering the icon only and not the label as well.
How can I change this behavior to accommodate the label as well? I would also prefer to have a more rectangular shape for the ink reaction.
Edit:
My code for the navigation bar
bottomNavigationBar: BottomNavigationBar(
type: BottomNavigationBarType.fixed,
selectedItemColor: Colors.blue[900],
unselectedItemColor: Colors.black87,
onTap: onTabTapped,
showUnselectedLabels: true,
currentIndex: _currentIndex,
items: const <BottomNavigationBarItem>[
BottomNavigationBarItem(
icon: Icon(Icons.home),
title: Text('Home'),
),
BottomNavigationBarItem(
icon: Icon(Icons.collections),
title: Text('Collections'),
),
BottomNavigationBarItem(
icon: Icon(Icons.phone),
title: Text('Recent'),
),
BottomNavigationBarItem(
icon: Icon(Icons.more_horiz),
title: Text('More'),
),
],
),
Current Behavior
Expected Behavior
After a few tries I figured that changing splashFactory could do the trick.
MaterialApp(
theme: ThemeData(
splashFactory: InkRipple.splashFactory,
),
)
After fiddling around with the flutter standard library, I now realised that BottomNavigationBarItem isn't a widget, but a container class to encapsulate the information that BottomNavigationBar need for its items.
Unfortunately, you will need to override BottomNavigationBar and create your own CustomBottomNavigationBar to do what you want.
The good news is that this is incredibly easy, since you only have to change one line of code. :)
I copied the code from $FLUTTER_HOME/packages/flutter/lib/src/material/bottom_navigation_bar.dart and made only one adjustment: at line 480, I changed InkResponse to InkWell and now it works as you wished.
With InkResponse:
With InkWell:
I suggest you to create an override folder in your project with the overridden classes, this is how I do it (I have overridden the default bottom sheet class):
Then, you can just import your overridden classes like this:
import 'package:your_project/widgets/override/bottom_navigation_bar.dart' as BottomNavigationBarOverride;
And use it like so:
bottomNavigationBar: BottomNavigationBarOverride.BottomNavigationBar(
type: BottomNavigationBarType.fixed,
selectedItemColor: Colors.blue[900],
unselectedItemColor: Colors.black87,
onTap: onTabTapped,
showUnselectedLabels: true,
currentIndex: _currentIndex,
items: const <BottomNavigationBarItem>[
BottomNavigationBarItem(
icon: Icon(Icons.home),
title: Text('Home'),
),
BottomNavigationBarItem(
icon: Icon(Icons.collections),
title: Text('Collections'),
),
BottomNavigationBarItem(
icon: Icon(Icons.phone),
title: Text('Recent'),
),
BottomNavigationBarItem(
icon: Icon(Icons.more_horiz),
title: Text('More'),
),
],
),
Old response
If you provide more code, I could help you out more.
Judging by the picture that you provided, this is intended behavior as bottom navigation itens aren't intended to be large. They are intend to be swift and clean as the material spec suggests:
If you intend to make only one "option", I suggest that you change your widget to a FlatButton. But be warned, this is against the spec as, for usability purposes, bottom navigation itens should contain at least 3 options and at max 5 options.