How to define content and code for a button icon - flutter

I have just started programming with Flutter and Dart
And I wanted to know how to set the code and content for a tab or button
For example, I put a button icon in the bottom navigator and what code and method is needed so that after clicking on that button, a new page will open one by one and the operation will be performed.
Thanks.

For bottom navigation bar you can use like this:
`
void _onItemTapped(int index) {
setState(() {
_selectedIndex = index;
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('BottomNavigationBar Sample'),
),
body: Center(
child: _widgetOptions.elementAt(_selectedIndex),
),
bottomNavigationBar: BottomNavigationBar(
items: const <BottomNavigationBarItem>[
BottomNavigationBarItem(
icon: Icon(Icons.home),
label: 'Home',
backgroundColor: Colors.red,
),
BottomNavigationBarItem(
icon: Icon(Icons.business),
label: 'Business',
backgroundColor: Colors.green,
),
BottomNavigationBarItem(
icon: Icon(Icons.school),
label: 'School',
backgroundColor: Colors.purple,
),
BottomNavigationBarItem(
icon: Icon(Icons.settings),
label: 'Settings',
backgroundColor: Colors.pink,
),
],
currentIndex: _selectedIndex,
selectedItemColor: Colors.amber[800],
onTap: _onItemTapped,
),
);
}
}
`
You need to set onTap() for actions when you press the button and setState() to update the state of the widget.
All buttons (TextButton, ElevatedButton ect) will be having onTap() property, you can call a method inside onTap().
For more details visit this: https://flutter.dev/docs/development/ui/widgets/material#Buttons

This is a very specific use case and has a different solution to what you would usually do with buttons.
The documentation for the BottomNavigationBar() shows a few code examples. You can copy paste that and modify it to suit your need. What they basically do is add BottomNavigationBar() items and add an onChanged/onTap method which you would use to change the page.
For buttons in general, they would have an onPressed parameter where you can pass a function or an anonymous function (e.g. () {your code here}). Flutter provides you with a few default buttons such as ElevatedButton() and TextButton() which you can read more about here (https://api.flutter.dev/flutter/material/ElevatedButton-class.html) and here (https://api.flutter.dev/flutter/material/TextButton-class.html). They have parameters which allow you to tweak them. This is where you can run functions when they are pressed.
If you want to make a non-button widget clickable you can use a GestureDetector() which you can read more about here (https://api.flutter.dev/flutter/widgets/GestureDetector-class.html). It is also has an onTap similar to the buttons but also has much more options such as long, double, triple, etc. taps as well as gestures like swipes.
It all comes down to getting used to all those different widgets and you will get familiar with them through practice.

Related

Flutter - How to position snackbar above system navigation bar

I have a transparent system navigation bar in my application.
Getx snack bar is used by the app to throw errors and success messages. What I'm stuck with is that anytime the app throws a snack bar, the snack bar appears and disappears through the transparent navigation bar (i can see the snack bar move through the navigation bar). Is there any way to have the snack bar appear above the navigation bar? How can I position the snack bar above the system navigation bar?
You may want to look into SnackBarBehavior enum which allows one to change the position. If you are using a third party library then you may want to try putting the behavior into an extension method. Alternative ideas exist on this SO Question that may apply in your use case although not an exact duplicate.
The SnackbarBehavior enum states:
Defines where a SnackBar should appear within a Scaffold and how its location should be adjusted when the scaffold also includes a FloatingActionButton or a BottomNavigationBar.
Other ideas include using a position widget with a Stack widget to gain precise control. Add a MediaQuery or other fractional widgets to allow for multiple screen sizes.
I suggest you to use SnackBar Widget that developed by flutter team instead of Getx snackbar. It basically appears above of navigation bar here an basic example;
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('BottomNavigationBar Sample'),
),
body: Center(
child: ElevatedButton(
child: const Text('Show Snackbar'),
onPressed: () {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: const Text('Awesome Snackbar!'),
action: SnackBarAction(
label: 'Action',
onPressed: () {
// Code to execute.
},
),
),
);
},
),
),
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,
),
);
}
static GetSnackBar SuccessSnackBar({String title = 'Success', String message}) {
Get.log("[$title] $message");
return GetSnackBar(
titleText: Text(title.tr, style: Get.textTheme.headline6.merge(TextStyle(color: Get.theme.primaryColor))),
messageText: Text(message, style: Get.textTheme.caption.merge(TextStyle(color: Get.theme.primaryColor))),
snackPosition: SnackPosition.BOTTOM,
margin: EdgeInsets.all(20),
backgroundColor: Colors.green,
icon: Icon(Icons.check_circle_outline, size: 32, color: Get.theme.primaryColor),
padding: EdgeInsets.symmetric(horizontal: 20, vertical: 18),
borderRadius: 8,
dismissDirection: DismissDirection.horizontal,
duration: Duration(seconds: 5),
);
}
Used like this in my app. Worked fine.
Get.snackbar(
"Bruh",
"Your quantity have to at least one",
colorText: Colors.black,
backgroundColor: Palette.yellowColor,
);
In my case, this is my return to show snackbar for error message, the snackbar appear on top below the appbar
In the getx snackbar there are a snackPosition: attribute
You can use that to display yours

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.

Flutter BottomNavigationBarItem accepts only Icon and no other widgets?

In our Flutter Cupertino project, we need to show a badge on one of the bottom bar icons. How many articles are already in the shopping cart to be precise.
I've tried different widgets and solutions provided here, but the BottomNavigationBarItem accepts only icon: Icon(..) and nothing else. If I, for example, put icon: Stack(..) instead of the icon: Icon(..), there are error messages shown, for example
"Invalid const value..."
Here is some sample code:
class CupertinoStoreHomePage extends StatelessWidget {
#override
Widget build(BuildContext context) {
return CupertinoTabScaffold(
tabBar: CupertinoTabBar(
items: const <BottomNavigationBarItem>[
BottomNavigationBarItem(
icon: Icon(CupertinoIcons.home),
title: Text('Kühlschrank'),
),
BottomNavigationBarItem(
icon: Icon(CupertinoIcons.profile_circled),
title: Text('Konto'),
),
BottomNavigationBarItem(
icon: Icon(CupertinoIcons.shopping_cart),
title: Text('Warenkorb'),
),
],
),
So if I can not put anything instead of the Icon(..). No other widget, no Stack(..).
Why? How can I put some other widget, like for example Badge(..):
badges: ^1.0.2
import 'package:badges/badges.dart';
This question is different from the possible duplicate, because I already tried the solution posted there and still can not use Stack(..) but only Icon(..).
I tried reproducing the problem, but it does work after changing a few things. First of all the icon property accepts a Widget and therefore not only an Icon, so this is not the problem.
I did notice however, in items: const <BottomNavigationBarItem>[ you should remove the const keyword as it is not necessary and also not constant.
And lastly, you need to add a tab builder to CupertinoTabScaffold this basically returns what's displayed above the bottom navigation bar.
Your final code then looks like this:
return CupertinoTabScaffold(
tabBuilder: (BuildContext context, int i) {
return CupertinoActivityIndicator();
},
tabBar: CupertinoTabBar(
items: <BottomNavigationBarItem>[
BottomNavigationBarItem(
icon: Badge(
badgeContent: Text('3'),
child: Icon(Icons.settings),
),
title: Text('Kühlschrank'),
),
BottomNavigationBarItem(
icon: Icon(CupertinoIcons.profile_circled),
title: Text('Konto'),
),
BottomNavigationBarItem(
icon: Icon(CupertinoIcons.shopping_cart),
title: Text('Warenkorb'),
),
],
),
);

Changing the Bottom Navigation Bar when switching between screens in the body of a Scaffold

HomeScreen() function call the Home screen of App.
How I Can route/move to "Team", "Add", etcetera page without BottomNavigationBar and AppBar.
I want show another page and back button, with new Bottom Navigation Bar.
I have this on my Flutter Project:
class APPMain extends StatefulWidget {
#override
_APPMainState createState() => _APPMainState();
}
class _APPMainState extends State<APPMain> {
int _currentIndex = 0;
_onTapped(int index) {
setState(() {
_currentIndex = index;
});
}
#override
Widget build(BuildContext context) {
List<Widget> screens = [
HomeScreen(),
Center(child: Text("Team")),
Center(child: Text("Add")),
Center(child: Text("Search")),
Center(child: Text("Settings")),
];
return Scaffold(
appBar: AppBar(
backgroundColor: Color(0xffffffff),
iconTheme: IconThemeData(color: Colors.grey),
title: Text("Test App", style: TextStyle(color: Colors.grey),),
actions: <Widget>[
IconButton(
icon: Icon(Icons.account_circle),
onPressed: (){},
),
],
),
body: Container(
color: Color(0xfff4f4f4),
child: Center(
child: screens[_currentIndex],
),
),
bottomNavigationBar: BottomNavigationBar(
currentIndex: _currentIndex,
type: BottomNavigationBarType.fixed,
fixedColor: Colors.red,
onTap: _onTapped,
items: [
BottomNavigationBarItem(
title: Text('Home'), icon: Icon(Icons.home)),
BottomNavigationBarItem(
title: Text('Team'), icon: Icon(Icons.group)),
BottomNavigationBarItem(
title: Text('Add'), icon: Icon(Icons.add)),
BottomNavigationBarItem(
title: Text('Search'), icon: Icon(Icons.search)),
BottomNavigationBarItem(
title: Text('Settings'), icon: Icon(Icons.settings)),
]),
);
}
}
Thank you so much for help.
This is almost certainly a duplicate but I wasn't able to find a question asking something similar with a quick search so I'll answer anyways.
The answer is actually quite simple, but requires understanding a bit more about how to write flutter applications - you should be using a Navigator or the navigator built right into MaterialApp or WidgetApp rather than making your own navigation. The simplest way is to use MaterialApp's routes property and pass in a map with each of your pages. Then when you want to switch pages, you simply use Navigator.pushNamed(context, <name>) from wherever you want to switch the page (i.e. a button).
The part that can be slightly confusing when you come from other frameworks is that rather than having one Scaffold and switching the body of it, the entire page should switch and each page should have a Scaffold.
Here's an example in the documentation showing how to navigate between pages.
For the record, although it's a bad idea you could make it work with your original code as well - all you'd have to do is build a different BottomNavigationBar with different options depending on what _currentIndex is set to. But I don't recommend that. With what I've suggested you also get animations between pages, back button functionality, you can hook up analytics to track page usage, and a bunch more things that flutter provides as part of navigation.