Issue with Row in Bottom App Bar that I'm not understanding - flutter

so I'm trying to implement a somewhat custom bottom navigation bar. I am trying to center my icons and after further investigation it is indeed working "correctly" in a way but the issue is that the bottom half of the bottom app bar gets completely ignored.
No matter what I do, the bottom half gets ignored. If I increase the size, it only makes it bigger at the top which is not what I want. How can I get the row to respect the entire bottom app bar?
Here's my code:
bottomNavigationBar: Padding(
padding: const EdgeInsets.only(left: 30, bottom: 33.0, right: 30.0),
child: ClipRRect(
borderRadius: BorderRadius.all(
Radius.circular(30.0),
),
child: BottomAppBar(
color: Color(0xFF222222),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Container(
height: 60.0,
child: SvgPicture.asset(
'assets/images/home.svg',
),
),
Container(
height: 60.0,
child: SvgPicture.asset(
'assets/images/discover.svg',
),
),
Container(
height: 60.0,
child: SvgPicture.asset(
'assets/images/heart.svg',
),
),
Container(
height: 60.0,
child: SvgPicture.asset(
'assets/images/user.svg',
),
),
],
),
),
),
),

Solution was to wrap BottomAppBar with SafeArea. Shoutout to Flutter discord for help on this :)
bottomNavigationBar: SafeArea(
child: Padding(
padding: const EdgeInsets.only(left: 30.0, right: 30.0),
child: ClipRRect(
borderRadius: BorderRadius.all(
Radius.circular(30.0),
),
child: BottomAppBar(
color: Color(0xFF222222),
child: Container(
height: 88.0,
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 30.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Stack(
children: [
IconButton(
onPressed: () {},
icon: SvgPicture.asset(
'assets/images/home.svg',
),
),
Positioned(
left: 23.0,
bottom: 0,
child: Image.asset('assets/images/Ellipse5.png'),
),
],
),
IconButton(
onPressed: () {},
icon: SvgPicture.asset(
'assets/images/discover.svg',
),
),
IconButton(
onPressed: () {},
icon: SvgPicture.asset(
'assets/images/heart.svg',
),
),
IconButton(
onPressed: () {},
icon: SvgPicture.asset(
'assets/images/user.svg',
),
),
],
),
),
),
),
),
),
),

Related

Flutter How to align row widget children to left and center

I am trying to create social login buttons like below image. I want to align textbutton icon and name to left. also center the row they are in so that the icon and text align vertically when using multiple text buttons.
expected result:
My Result:
My Code for button:
TextButton(
onPressed: onTap,
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Align(
alignment: Alignment.centerLeft,
child: Container(
margin: const EdgeInsets.symmetric(horizontal: 20),
width: 30,
child: Image.asset(
icon,
fit: BoxFit.cover,
),
),
),
Align(
alignment: Alignment.centerLeft,
child: Text(
buttonName,
style: kBodyText2,
textAlign: TextAlign.left,
),
),
],
),
style: TextButton.styleFrom(
backgroundColor: Colors.white,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(SizeConfig.blockSizeH! * 3),
),
),
),
You should use ListTile()
instead.
Set title: "Continue with Google".
And leading: you can set the logo.
The positions will always stay the same no matter how long your title will be, you also have extra options like subtitles and trailing actions.
To make it act like a button use
onTap: (){}
You can achieve that by using the Expanded widget: Like so:
Padding(
padding: const EdgeInsets.all(8.0),
child: TextButton(
onPressed: (){},
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Expanded(
flex: 1,
child: Container(),),
Expanded(
flex: 2,
child: Align(
alignment: Alignment.centerLeft,
child: Container(
margin: const EdgeInsets.symmetric(horizontal: 20),
width: 30,
child: Icon(Icons.access_alarm),
),
),
),
Expanded(
flex: 5,
child: Align(
alignment: Alignment.centerLeft,
child: Text(
'test text test',
textAlign: TextAlign.left,
),
),
),
],
),
style: TextButton.styleFrom(
backgroundColor: Colors.grey,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10),
),
),
),
),
const SizedBox(height: 30),
Padding(
padding: const EdgeInsets.all(8.0),
child: TextButton(
onPressed: (){},
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Expanded(flex: 1, child: Container(),),
Expanded(
flex: 2,
child: Align(
alignment: Alignment.centerLeft,
child: Container(
margin: const EdgeInsets.symmetric(horizontal: 20),
width: 30,
child: Icon(Icons.access_alarm),
),
),
),
Expanded(
flex: 5,
child: Align(
alignment: Alignment.centerLeft,
child: Text(
'test text test test',
textAlign: TextAlign.left,
),
),
),
],
),
style: TextButton.styleFrom(
backgroundColor: Colors.grey,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10),
),
),
),
),
You can exploit the fact the these icons are the same size, to easily align them. Each of your TextButton already holds a Row, but instead of fancy layout stuff, you can just insert padding to the Icon by adding blank spaces using SizedBox, like so:
TextButton(
child: Row(
children: [
const SizedBox(width: 16), // padding in the beginning
Icon(Icons.download), // the icon, or image, or whatever
const SizedBox(width: 16), // padding in-between
Text('Button ' * i), // the text
],
),
onPressed: () {},
)
Result:
Code used to produce the above demo:
Column(
mainAxisSize: MainAxisSize.min,
children: [
for (int i = 1; i < 6; i++)
TextButton(
child: Row(
children: [
const SizedBox(width: 16),
Icon(Icons.download),
const SizedBox(width: 16),
Text('Button ' * i),
],
),
onPressed: () {},
style: TextButton.styleFrom(
backgroundColor: Colors.white,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(16),
),
),
),
],
)

See attached snapshot. I have created such circle box through container in flutter. But I am seeking for widget. Do flutter have a widget for it?

Hi. I have attached a snapshot. Can anyone tell me how I can get this circle image and below text in one widget ? Is there any such single widget in flutter ? Instead of using 3 widgets column, container and text widgets.
[![Attached Snapshot][1]]
[1]: https://i.stack.imgur.com/TlLwK.png
you can add circular avtar to make like you picture
Container(
padding: EdgeInsets.only(left: 15, right: 15, top: 10),
child: Row(
children: [
Column(
children: [
Container(
height: 40,
width: 40,
child: CircleAvatar(
backgroundImage: AssetImage("")),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: Text('Nike'),
),
],
),
Column(
children: [
Container(
height: 40,
width: 40,
child: CircleAvatar(
backgroundImage: AssetImage("")),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: Text('Nike'),
),
],
),
Column(
children: [
Container(
height: 40,
width: 40,
child: CircleAvatar(
backgroundImage: AssetImage("")),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: Text('Nike'),
),
],
),
Column(
children: [
Container(
height: 40,
width: 40,
child: CircleAvatar(
backgroundImage: AssetImage("")),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: Text('Nike'),
),
],
),
],
),
),
Try below code hope it solve your problem:
ButtonBar(
alignment: MainAxisAlignment.spaceAround,
children: [
Column(
children: [
ElevatedButton(
onPressed: () {},
child: Icon(Icons.check, color: Colors.white),
style: ElevatedButton.styleFrom(
shape: CircleBorder(),
padding: EdgeInsets.all(20),
primary: Colors.grey, // <-- Button color
onPrimary: Colors.red, // <-- Splash color
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: Text('Nike'),
),
],
),
Column(
children: [
ElevatedButton(
onPressed: () {},
child: Icon(Icons.add, color: Colors.white),
style: ElevatedButton.styleFrom(
shape: CircleBorder(),
padding: EdgeInsets.all(20),
primary: Colors.grey, // <-- Button color
onPrimary: Colors.red, // <-- Splash color
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: Text('Add'),
),
],
),
Column(
children: [
ElevatedButton(
onPressed: () {},
child: Icon(Icons.edit, color: Colors.white),
style: ElevatedButton.styleFrom(
shape: CircleBorder(),
padding: EdgeInsets.all(20),
primary: Colors.grey, // <-- Button color
onPrimary: Colors.red, // <-- Splash color
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: Text('Edit'),
),
],
),
Column(
children: [
ElevatedButton(
onPressed: () {},
child: Icon(Icons.menu, color: Colors.white),
style: ElevatedButton.styleFrom(
shape: CircleBorder(),
padding: EdgeInsets.all(20),
primary: Colors.grey, // <-- Button color
onPrimary: Colors.red, // <-- Splash color
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: Text('Menu'),
),
],
),
],
),
Your Screen like ->

What is the best flutter widget to use to achieve this kinda layout?

This is the UI I want to implement, I only started playing with flutter last week so I am not as fluent. I was wondering what is the best way to achieve this layout.
This is what I get with a stack and column:
This is the code:
Column(
children: <Widget>[
Expanded(
child: Container(
constraints: BoxConstraints.expand(height: 150),
color: Colors.blue,
child: Stack(
overflow: Overflow.visible,
children: <Widget>[
Positioned(
bottom: -40,
left: MediaQuery.of(context).size.width * 0.4,
// alignment: Alignment.bottomCenter,
child: Container(
constraints: BoxConstraints.expand(height: 80, width: 80),
color: Colors.green,
),
),
],
),
),
flex: 3,
),
Expanded(
child: Container(
margin: EdgeInsets.all(15.0),
color: Colors.red,
),
flex: 7,
)
],
);
I made something like the image you provided with dummy image and some icon you can change icons if you want,use media query size instead of fixed padding tops
class _MyHomePageState extends State<MyHomePage> {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: SingleChildScrollView(
child: Column(
children: [
Stack(children: [
Container(
child: FittedBox(
fit: BoxFit.fill,
child: Image.network('https://picsum.photos/300?image=10')),
height: 150,
width: double.infinity,
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
Padding(
padding: const EdgeInsets.only(top: 75),
child: MaterialButton(
onPressed: () {},
elevation: 2.0,
color: Colors.red,
child: Icon(
Icons.message,
size: 27.0,
),
padding: EdgeInsets.all(20),
shape: CircleBorder(),
),
),
Padding(
padding: const EdgeInsets.only(top: 75),
child: Column(children: [
CircleAvatar(
radius: 55.0,
backgroundImage:
NetworkImage('https://i.pravatar.cc/150?img=54'),
backgroundColor: Colors.transparent,
),
Text("David Beckham"),
Text("Model/SuperStar")
]),
),
Padding(
padding: const EdgeInsets.only(top: 75),
child: MaterialButton(
onPressed: () {},
elevation: 2.0,
color: Colors.blue,
child: Icon(
Icons.add,
size: 27.0,
),
padding: EdgeInsets.all(20),
shape: CircleBorder(),
),
),
],
),
]),
Container(height: 100, color: Colors.red),
Container(height: 100, color: Colors.green),
Container(height: 100, color: Colors.yellow),
Container(height: 100, color: Colors.blue),
],
)));
}
}

How do I add a splash effect on a card using GestureDetector

I wan't to add splash effect over the card when tapped on it.
I referred some of the answers on stackoverflow but, nothing caught up in my brai. HELP!!
My Code -
body: Container(
padding: EdgeInsets.all(10),
child: ListView(
children: <Widget>[
Container(
height: 100,
child: GestureDetector(
onTap: () {
Navigator.pushNamed(context, '/page1');
},
child: GradientCard(
gradient: LinearGradient(
colors: [Colors.yellow, Colors.lightGreenAccent]),
elevation: 10,
child: Padding(
padding:
const EdgeInsets.symmetric(vertical: 10, horizontal: 8),
child: Center(
child: Row(
children: <Widget>[
SizedBox(width: 25),
Icon(
Icons.favorite,
color: Colors.redAccent,
size: 50,
),
SizedBox(width: 40),
Text(
"MY CARD",
style: TextStyle(fontSize: 28),
),
],
),
),
),
),
),
),
],
),
),
I also tried to wrap onTap: function with InkWell with an ancestor as Material, But it won't let me to do so. Actually, I am confused now and stucked. Any help will be apperiated!!
Try this and let me know if that works!
Container(
padding: EdgeInsets.all(10),
child: ListView(
children: <Widget>[
Container(
height: 100,
child: GradientCard(
gradient: LinearGradient(
colors: [Colors.yellow, Colors.lightGreenAccent]
),
elevation: 10,
child: Material(
color: Colors.transparent,
child: InkWell(
onTap: () {
Navigator.pushNamed(context, '/page1');
},
child: Padding(
padding: const EdgeInsets.symmetric(vertical: 10, horizontal: 8),
child: Center(
child: Row(
children: <Widget>[
SizedBox(width: 25),
Icon(
Icons.favorite,
color: Colors.redAccent,
size: 50,
),
SizedBox(width: 40),
Text(
"MY CARD",
style: TextStyle(fontSize: 28),
),
],
),
),
),
)
)
)
),
],
),
);
Try this:
Container(
height: 100,
child: Material(
elevation: 10,
color: Theme.of(context).cardColor,
child: InkWell(
onTap: () {
Navigator.pushNamed(context, '/page1');
},
child: Center(
child: Row(
children: <Widget>[
SizedBox(width: 25),
Icon(
Icons.favorite,
color: Colors.redAccent,
size: 50,
),
SizedBox(width: 40),
Text(
"MY CARD",
style: TextStyle(fontSize: 28),
),
],
),
),
),
),
)

How to show a Container fixed at bottom of screen without using bottom navigation bar in Flutter?

In my flutter project, I have a container with some icons and text below them. I want this entire container to be fixed at bottom of the screen without using bottom navigation bar like the below image-
So, I need an entire example to fix that container at bottom and keep my other components inside body with a scroll view.
Ok,
Here you go....
return Scaffold(
appBar: AppBar(
title: Text("Header"),
),
body: Column(
children: <Widget>[
Expanded(
child: Container(
alignment: Alignment.center,
child: Text("Hello"),
),
),
Container(
height: 50,
width: double.maxFinite,
decoration: BoxDecoration(
color: Colors.deepOrange,
borderRadius: BorderRadius.vertical(top: Radius.circular(20.0))
),
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
IconButton(icon: Icon(Icons.arrow_forward), onPressed: (){},),
IconButton(icon: Icon(Icons.arrow_downward), onPressed: (){},),
IconButton(icon: Icon(Icons.arrow_left), onPressed: (){},),
IconButton(icon: Icon(Icons.arrow_upward), onPressed: (){},),
],
),
)
],
),
);
If you want to make a scrollable item/listview in the body section and want a fixed bottom container you can follow this code given below :
important note : Make sure wrap the listview with Expanded
import 'package:flutter/material.dart';
class ShoppingCart extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.grey[200],
appBar: AppBar(
backgroundColor: Colors.white,
leading: IconButton(
icon: Icon(Icons.arrow_back, color: Colors.black),
),
actions: <Widget>[
GestureDetector(
onTap: () {
//your code
},
child: Padding(
padding: const EdgeInsets.only(right: 15.0),
child: Icon(
Icons.delete_outline_sharp,
color: Colors.black,
size: 30,
),
)),
//Add more icon here
],
elevation: 0,
centerTitle: false,
title:
Text("Shopping Cart", style: TextStyle(color: Colors.black))),
body: Column(
children: [
Expanded(
child: ListView.builder(
itemCount: shoppingCartItems.length,
itemBuilder: (context, index) {
return Padding(
padding: const EdgeInsets.only(
top: 15.0, left: 12.0, right: 12.0),
child: Container(
decoration: BoxDecoration(
// color: Color(0xffF3F3F3),
color: Colors.red,
shape: BoxShape.rectangle,
borderRadius:
BorderRadius.all(Radius.circular(10.0))),
height: 120,
width: 360,
),
);
},
),
),
Container(
height: 150,
width: double.maxFinite,
decoration: BoxDecoration(
color: Colors.deepOrange[200],
borderRadius:
BorderRadius.vertical(top: Radius.circular(20.0))),
)
],
));
}
}
Update :
This is built in now. You can use bottomNavigationBar and customize is as below :
bottomNavigationBar: BottomAppBar(
child: Container(
height: //set your height here
width: double.maxFinite, //set your width here
decoration: BoxDecoration(
color: Colors.orange,
borderRadius: BorderRadius.vertical(top: Radius.circular(20.0))
),
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
IconButton(icon: Icon(Icons.arrow_forward), onPressed: (){
//on Presses functionaluty goes here
},),
//add as many tabs as you want here
],
),
),
),
bottomNavigationBar: BottomAppBar(
child: Container(
height: 50.0,
width: double.maxFinite,
decoration: BoxDecoration(
color: Colors.deepOrange,
borderRadius: BorderRadius.vertical(top: Radius.circular(20.0))
),
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
IconButton(icon: Icon(Icons.arrow_forward), onPressed: (){},),
IconButton(icon: Icon(Icons.arrow_downward), onPressed: (){},),
IconButton(icon: Icon(Icons.arrow_left), onPressed: (){},),
IconButton(icon: Icon(Icons.arrow_upward), onPressed: (){},),
],
),
),
),