How do I remove the white area from BottomAppBar Flutter IOS - flutter

I have this bottomAppBar problem in Flutter on an Iphone. I don't know why but there is this white area on the bottom and when I change the theme of the app, it didn't change with it (only when I put this bottomAppBar) Does someone know how to fix that ? Thanks
bottomNavigationBar: BottomAppBar(
child:
Container(
color: Color.fromRGBO(10, 10, 10, 1),
height: 60,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Row(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
IconButton(
onPressed: () {
setState(() {
currentScreen = Fy();
currentTab = 0;
});
},
iconSize: 40,
icon: const Icon(Icons.home),
color: currentTab == 0 ? Colors.blue : Colors.grey,
),
MaterialButton(
onPressed: () {
setState(() {
currentScreen = const Search();
currentTab = 1;
});
},
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(
Icons.search,
size: 40,
color: currentTab == 1 ? Colors.blue : Colors.grey,
),
],
),
),
]
),
],
),
)
));
}
}

Do you have a SafeArea widget somewhere up the tree from your bottom navigation bar? If so, set the bottom property of it to false. This will make you UI build right to the bottom of the screen.

Related

How to get a floating box when i click on a button in flutter

I want to make this type of UI -
Like this dialog opens when we click on "Other Details" and appears just below it. Is there any package for this? Else I will try to use stack and positioned, and will position it as accurate as I can.
You could use an ExpansionTile.
It does exactly what you are looking for.
Code sample:
Center(
child: ExpansionTile(
iconColor: Colors.red,
title: const Text('More details'),
children: [
ListTile(
title: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: const [
Text('Name'),
Text('Ankit'),
],
)),
ListTile(
title: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: const [
Text('Grade'),
Text('9th'),
],
)),
ListTile(
title: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: const [
Text('Date of birth'),
Text('21-04-2008'),
],
)),
],
),
)
Keep in mind that in the children you could put any widget, even a container, as:
EDIT
After reading your clarifying comment this is what I made:
Obviously it's a basic floating box, but you can customize it.
I used a Stack to overlap widgets and a boolean to check if you need to show or not the infobox.
bool visibile = false;
Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
IconButton(
onPressed: () => setState(() {
visibile = !visibile;
}),
icon: const Icon(Icons.remove_red_eye)),
Stack(
alignment: Alignment.center,
children: [
Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
children: const [
ElevatedButton(
onPressed: null,
child: Text("Check In"),
),
TextField()
],
),
),
visibile
? Container(
width: MediaQuery.of(context).size.width * .8,
height: MediaQuery.of(context).size.height * .5,
decoration: BoxDecoration(
color: Colors.white,
boxShadow: [
BoxShadow(
offset: Offset.fromDirection(1, 2),
spreadRadius: 1,
blurRadius: 3,
color: Colors.grey)
],
borderRadius: const BorderRadius.all(Radius.circular(20)),
border: Border.all(
color: Colors.orange,
width: 2,
style: BorderStyle.solid)),
child: Padding(
padding: const EdgeInsets.all(20.0),
child: SingleChildScrollView(
child: Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: const [
Text(
'Academic year',
style: TextStyle(color: Colors.grey),
),
Text('2023'),
],
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: const [
Text(
'Student name',
style: TextStyle(color: Colors.grey),
),
Text('Ankit'),
],
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: const [
Text(
'Grade',
style: TextStyle(color: Colors.grey),
),
Text('9th'),
],
),
],
),
),
),
)
: Container(),
],
),
],
))
Having the button outside the Stack prevents the InfoBox to hide it and makes it so you can click it at any time.
I have no idea why, but someone with enough privileges keeps deleting my comments on this answer.
You could use the native Flutter Widget https://api.flutter.dev/flutter/material/ExpansionPanel-class.html or try a package like https://pub.dev/packages/expandable
If you Want the widget float on the other widgets, you can use OverlayEntry. There is a medium article/guide about this: Click to read.
Abstract:
first you need a global key, an overlay widget and the other variables below:
GlobalKey overlayKey = LabeledGlobalKey("button_icon");
late OverlayEntry overlayEntry;
late Size buttonSize;
late Offset buttonPosition;
bool isMenuOpen = false;
then add the global key to your button's key proprty:
key: context.read<MainViewModel>().overlayKey,
then, find the clicked button using this function:
findButton() {
RenderBox renderBox =
overlayKey.currentContext!.findRenderObject() as RenderBox;
buttonSize = renderBox.size;
buttonPosition = renderBox.localToGlobal(Offset.zero);
}
then, a builder:
OverlayEntry overlayEntryBuilder() {
return OverlayEntry(
builder: (context) {
return Positioned(
top: buttonPosition.dy + buttonSize.height * 4 / 5,
left: buttonPosition.dx - (buttonSize.width / 2) - 32,
// width: buttonSize.width,
child: YourWidgetThatWillOpenWhenYouClickTheButton(),
);
},
);
}
you can play around with the values in the Positioned widget to get the overlay where you want it.
now you can call these functions to open/close the overlay:
void openMenu(BuildContext context) {
findButton();
overlayEntry = overlayEntryBuilder();
Overlay.of(context)!.insert(overlayEntry);
isMenuOpen = !isMenuOpen;
}
void closeMenu() {
overlayEntry.remove();
isMenuOpen = !isMenuOpen;
}
like this:
IconButton(
key: context.read<MainViewModel>().overlayKey,
onPressed: () {
if (!context.read<MainViewModel>().isMenuOpen) {
context.read<MainViewModel>().openMenu(context);
} else {
context.read<MainViewModel>().closeMenu();
}
},
check the medium article for the detailed explanation.

How to change tab programmatically on BottomAppBar flutter?

I am working on a flutter application where I need to change my tab programmatically, here If I came on the last screen of the stack then I need to redirect to the first tab programmatically instead of closing the app.
Please consider the following code snnipet:
final PageStorageBucket bucket = PageStorageBucket();
Widget currentScreen = HomeFragment();
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Color(0xFFF3F5F9),
body: PageStorage(
child: currentScreen,
bucket: bucket,
),
bottomNavigationBar: BottomAppBar(
shape: CircularNotchedRectangle(),
child: Container(
width: double.infinity,
height: 15.5,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
GestureDetector(
onTap: () {
setState(() {
currentScreen = HomeFragment();
currentTab = 0;
});
},
child: Expanded(
child: Container(
height: 15.5,
color: Colors.white,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Image.asset(
'assets/home.png',
color: currentTab == 0 ? Color(0xFF193F70) : Color(0xFFABAAAA),
),
SizedBox(
height: 3.0,
),
Text(
'Home',
),
],
),
),
),
),
GestureDetector(
onTap: () {
setState(() {
redirectToLogin();
});
},
child: Expanded(
child: Container(
height: 15.5,
color: Colors.white,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Image.asset(
'assets/login_icon.png',
color: currentTab == 1 ? Color(0xFF193F70) : Color(0xFFABAAAA),
),
SizedBox(
height: 3.0,
),
Text(
'Login',
),
],
),
),
),
),
GestureDetector(
onTap: () {
setState(() {
redirectToSignUp();
});
},
child: Expanded(
child: Container(
height: 15.5,
color: Colors.white,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Image.asset(
'assets/signup_icon.png',
color: currentTab == 2 ? Color(0xFF193F70) : Color(0xFFABAAAA),
),
SizedBox(
height: 3.0,
),
Text(
'SignUp',
),
],
),
),
),
),
GestureDetector(
onTap: () {
setState(() {
currentScreen = ProfileFrag();
currentTab = 3;
});
},
child: Expanded(
child: Container(
height: 15.5,
color: Colors.white,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Image.asset(
'assets/menu_icon.png',
color: currentTab == 3 ? Color(0xFF193F70) : Color(0xFFABAAAA),
),
SizedBox(
height: 3.0,
),
Text(
'Menu',
),
],
),
),
),
),
],
),
),
),
);}
Here I am looking for something that can redirect to a different tab programmatically. Also please let me know if I am doing something wrong here.
I believe it would be better to use a real Flutter TabBar. Have you considered this solution?
There is a complete tutorial on this blog : https://blog.logrocket.com/flutter-tabbar-a-complete-tutorial-with-examples/
It includes a way to change tabs programmatically. This is actually what I am trying to do with my own app.
Let me know if this could work for you.

Flutter: Expanded IconButton still shows under the Container

AnimatedContainer(
...
child: Container(
child: Column(
children: [
Row(
children: [
Container(
width:60,
height:50,
color: Colors.black,
),
],
),
Expanded(
child: GestureDetector(
onTap: () {
print('what');
},
child: Container(
height: 50,
child: Column(
children: [
Expanded(
child: Text('asdf'),
),
Expanded(
child: IconButton(
icon: Icon(Icons.ac_unit),
onPressed: () {},
),
I have this AnimatedContainer widget here. My Text() widget and RaisedButton widget are hidden inside the box. They appear as the AnimatedContainer expand. However, my IconButton doesn't.
Also, Icon widget also stays like IconButton widget. How can I make it appear when the AnimatedContainer is stretched like the Text widget?
I've modified your code, hope this is what u want.
class _RowStructureState extends State<RowStructure> {
bool pressed = false;
#override
Widget build(BuildContext context) {
return GestureDetector(
onTap: () {
setState(() {
pressed = !pressed;
});
print(pressed);
},
child: Column(children: <Widget>[
AnimatedContainer(
height: pressed ? 120 : 50,
color: Colors.green,
duration: Duration(seconds: 1),
child: Stack(
children: [
Container(
height: 50,
width: 50,
color: Colors.black,
),
Positioned(
bottom:0,
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: [
Text('asd'),
IconButton(
padding: EdgeInsets.all(0),
icon: Icon(Icons.ac_unit,),
onPressed: pressed?(){}:null,
),
],
),
)
],
),
)
]),
);
}
}

track which container was clicked on in flutter

I have 3 containers and in each picture, when you click on which an icon appears. How to assign a value to each container, so that when you click it, you can change it too. Or how to track which container was clicked on
class _EditAccountScreenState extends State<EditAccountScreen> {
bool checkboxValue = false;
...
child: GestureDetector(
onTap: () {
setState(() {
checkboxValue = !checkboxValue;
});
},
child: Padding(
child: Row(
children: <Widget> [
Container(
child: Stack(
children: <Widget>[
Image.asset('assets/images/telegram-512.png',fit: BoxFit.fill),
Positioned(
bottom: 0, right: 15, //give the values according to your requirement
child: checkboxValue
? Container(
decoration: BoxDecoration(
color: Colors.green,
borderRadius:BorderRadius.circular(100)
),
child: Icon(
Icons.check,
color: Colors.white,
size: 15,
)
)
: Container(),),],),),
Container(
child: Stack(
children: <Widget>[
Image.asset('assets/images/Viber-Logo.png',fit: BoxFit.fill),
Positioned(
bottom: 0, right: 15, //give the values according to your requirement
child: checkboxValue
? Container(
decoration: BoxDecoration(
color: Colors.green,
borderRadius:BorderRadius.circular(100)
),
child: Icon(
Icons.check,
color: Colors.white,
size: 15,
)
)
: Container(),),],),),
Use Gesture Detector to detect Taps on containers.
Here is an example related to this:
Container(
alignment: FractionalOffset.center,
color: Colors.white,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Padding(
padding: const EdgeInsets.all(8.0),
child: Icon(
Icons.lightbulb_outline,
color: _lights ? Colors.yellow.shade600 : Colors.black,
size: 60,
),
),
GestureDetector(
onTap: () {
setState(() {
_lights = true;
});
},
child: Container(
color: Colors.yellow.shade600,
padding: const EdgeInsets.all(8),
child: const Text('TURN LIGHTS ON'),
),
),
],
),
)
First of All Make a Integer Variable and then set its value to -1 by default
int selectedContainerIndex = -1;
Now, You Can Wrap each of your Container in seperate GestureDetector, and then on the onTap method you can set the selectedContainerIndex value of your container according to you.
See the below Code
Stack(
children: [
//First Container
GestureDetector(
onTap: () {
selectedContainerIndex = 0;
setState(() {});
},
child: new Container(),
),
//Second Container
GestureDetector(
onTap: () {
selectedContainerIndex = 1;
setState(() {});
},
child: new Container(),
),
//Third Container
GestureDetector(
onTap: () {
selectedContainerIndex = 2;
setState(() {});
},
child: new Container(),
),
],
),
Now To know which Container was tapped you can always use the selectedContainerIndex Value
print(selectedContainerIndex);
NOTE: If your containers are more in numbers say 4 or 5, then I would recommend you to use good practice and show those using some dynamic listview builder, instead of hardcoding them each.

extendBody with custom BottomNavBar and FAB not working properly

I've searched around for similar problems like this but couldn't find any.
I made a custom bottom navigation bar with a docked FAB. As far as i understand, to make the notch for the FAB transparent I need to add extendBody = true; to the Scaffold, which i did. The result is that out of the four navbar icons, only one of them are showing the transparent notch.
Code and images below. Images are showing second and third navbar icon.
Scaffold(
drawerEnableOpenDragGesture: true,
extendBody: true,
appBar: AppBar(
title: Text('Some text'),
drawer: AppDrawer(),
bottomNavigationBar: BottomAppBar(
color: Colors.blue,
shape: CircularNotchedRectangle(),
notchMargin: 2.0,
child: Container(
height: MediaQuery.of(context).size.width * 0.15,
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Expanded(
flex: 4,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
IconButton(icon: Icon(Icons.account_box), // extendBody not working!
onPressed: () {
setState(() {
_selectedPageIndex = 0;
});
},
),
IconButton(icon: Icon(Icons.account_box), // extendBody working!
onPressed: () {
setState(() {
_selectedPageIndex = 1;
});
},
),
],
),
),
Expanded(flex: 2, child: SizedBox()),
Expanded(
flex: 4,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
IconButton(icon: Icon(Icons.email), // extendBody not working!
onPressed: () {
setState(() {
_selectedPageIndex = 2;
});
},
),
IconButton(
icon: Icon(Icons.email), // extendBody not working!
onPressed: () {
setState(() {
_selectedPageIndex = 3;
});
},
),
],
),
),
],
),
),
),
floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,
body: _pages[_selectedPageIndex]['page'],
floatingActionButton: FloatingActionButton(
mini: true,
onPressed: () {
if (_selectedPageIndex == 0)
Navigator.of(context).pushReplacementNamed(
Screen1.routeName);
if (_selectedPageIndex == 1)
Navigator.of(context).pushReplacementNamed(
Screen2.routeName);
if (_selectedPageIndex == 2)
Navigator.of(context).pushReplacementNamed(
Screen3.routeName);
if (_selectedPageIndex == 3)
Navigator.of(context).pushReplacementNamed(
Screen4.routeName);
},
child: _pages[_selectedPageIndex]['icon'],
backgroundColor: Theme.of(context).accentColor,
),
)
What am I missing? Thank you!
I solved it. extendBody: true, is correct, however the child cannot be wrapped in SafeArea.