I am new to Flutter, I am trying to show two buttons in a row at the bottom,
I have tried all possible solutions, including Align, Expanded etc but it didn't work..
Please if someone can help, as my buttons don't go at the bottom of screen
Here's my code:
return Scaffold(
body: SingleChildScrollView(
child: Column(children: [
Container(
//code
),
Container(
//code
),
Row(
children: [
ConstrainedBox(
constraints: BoxConstraints.tightFor(width: 100, height: 80),
child: ElevatedButton(
child: Text(
'Register',
style: TextStyle(
color: Colors.white,
fontSize: 15.0,
),
),
style: ElevatedButton.styleFrom(
primary: Colors.blue.shade900,
),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => Intro()),
);
},
),
),
ConstrainedBox(
constraints: BoxConstraints.tightFor(width: 100, height: 80),
child: ElevatedButton(
child: Text(
'Register',
style: TextStyle(
color: Colors.white,
fontSize: 15.0,
),
),
style: ElevatedButton.styleFrom(
primary: Colors.blue.shade900,
),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => Intro()),
);
},
),
),
],
),
]),
),
);
Here is a solution involving the bottomNavigationBar property of the Scaffold widget where you can put any Widget? (here, we're using your Row):
You can play around with the provided code on this dartpad.
Here's the result:
return Scaffold(
bottomNavigationBar: Padding(
padding: EdgeInsets.all(20),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
ConstrainedBox(
constraints: BoxConstraints.tightFor(width: 100, height: 80),
child: ElevatedButton(
child: Text(
'Register',
style: TextStyle(
color: Colors.white,
fontSize: 15.0,
),
),
style: ElevatedButton.styleFrom(
primary: Colors.blue.shade900,
),
onPressed: () {},
),
),
ConstrainedBox(
constraints: BoxConstraints.tightFor(width: 100, height: 80),
child: ElevatedButton(
child: Text(
'Register',
style: TextStyle(
color: Colors.white,
fontSize: 15.0,
),
),
style: ElevatedButton.styleFrom(
primary: Colors.blue.shade900,
),
onPressed: () {},
),
),
],
),
),
body: SingleChildScrollView(
child: Column(children: [
Container(
//code
),
Container(
//code
),
]),
),
);
Here is your updated code, Please check
Scaffold(
body: Column(mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [
SingleChildScrollView(
child: Column(
children: [
Container(
//code
),
Container(
//code
),
],
),
),
Row(
children: [
ConstrainedBox(
constraints: BoxConstraints.tightFor(width: 100, height: 80),
child: ElevatedButton(
child: Text(
'Register',
style: TextStyle(
color: Colors.white,
fontSize: 15.0,
),
),
style: ElevatedButton.styleFrom(
primary: Colors.blue.shade900,
),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => Intro()),
);
},
),
),
ConstrainedBox(
constraints: BoxConstraints.tightFor(width: 100, height: 80),
child: ElevatedButton(
child: Text(
'Register',
style: TextStyle(
color: Colors.white,
fontSize: 15.0,
),
),
style: ElevatedButton.styleFrom(
primary: Colors.blue.shade900,
),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => Intro()),
);
},
),
),
],
),
]),
),
OR
You can use bottomSheet method of scaffold
Scaffold(
bottomSheet: Padding(
padding: const EdgeInsets.only(bottom: 10),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
ConstrainedBox(
constraints: BoxConstraints.tightFor(width: 100, height: 80),
child: ElevatedButton(
child: Text(
'Register',
style: TextStyle(
color: Colors.white,
fontSize: 15.0,
),
),
style: ElevatedButton.styleFrom(
primary: Colors.blue.shade900,
),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => Intro()),
);
},
),
),
SizedBox(width: 50),
ConstrainedBox(
constraints: BoxConstraints.tightFor(width: 100, height: 80),
child: ElevatedButton(
child: Text(
'Register',
style: TextStyle(
color: Colors.white,
fontSize: 15.0,
),
),
style: ElevatedButton.styleFrom(
primary: Colors.blue.shade900,
),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => Intro()),
);
},
),
),
],
),
),
body: SingleChildScrollView(
child: Column(children: [
Column(
children: [
Container(
//code
),
Container(
//code
),
],
),
]),
),
),
The row will match its childrens height so because all buttons have the same height your final row is 80 (px) in height and therefore it doesnt matter where to align buttons. You can wrap your row in a container with color to see it.
The corruct solution would be to give the row height by wrapping it in a diffrent widget (like column) and stretch it to available space. Then inside the row you just need CrossAxisAlignment.end. But this depends on your layout.
For example:
Column(
mainAxisSize: MainAxisSize.max,
children: [
Expanded(
row: Row(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
/* Buttons here **/
]),
)
]
)
You can also refer to the flutter layout guide and CSS Flexbox as it almost translates 1-1 to flutter and
Related
the question is exactly same as this post
but I did not find an answer from the post.
my goal is to set the title widget in the center
and other two buttons on the right side.
the solutions in the link all put the title widget slightly on the left side.
does anyone know how to do this without using Stack? I'm afraid of the title widget being over the button widgets when the title gets too long.
the code:
SizedBox(
height: 40,
width: MediaQuery.of(context).size.width,
child: Row(
children: [
const SizedBox(width: 17),
Text(
'TITLE',
style: const TextStyle(
color: Colors.white, fontSize: 30, fontWeight: FontWeight.w500),
),
Spacer(),
Row(
children: [
GestureDetector(
onTap: (){null;},
child: SizedBox(
child: Icon(Icons.wallet_membership, color: Colors.white),
),
),
const SizedBox(width: 17),
GestureDetector(
onTap: (){Get.toNamed('/wallet_setting');},
child: const SizedBox(
child: Icon(Icons.settings, color: Colors.white),
),
),
]
)
]
),
)
Try this One
Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
Expanded(
child: Container(
child: Center(
child: Text(
'TITLE',
style: const TextStyle(color: Colors.white, fontSize: 30, fontWeight: FontWeight.w500),
),
)
)
),
Align(
alignment: Alignment.centerRight,
child: Row(
children: [
GestureDetector(
onTap: (){null;},
child: SizedBox(
child: Icon(Icons.wallet_membership, color: Colors.white),
),
),
const SizedBox(width: 17),
GestureDetector(
onTap: (){Get.toNamed('/wallet_setting');},
child: const SizedBox(
child: Icon(Icons.settings, color: Colors.white),
),
),
]
)
)
],
)
OutPut:
i think you should wrap it with centre
Try this approach:
first make widget from your right widgets:
Widget _rightIcons() {
return Row(children: [
GestureDetector(
onTap: () {
null;
},
child: SizedBox(
child: Icon(Icons.wallet_membership, color: Colors.white),
),
),
const SizedBox(width: 17),
GestureDetector(
onTap: () {
Get.toNamed('/wallet_setting');
},
child: const SizedBox(
child: Icon(Icons.settings, color: Colors.white),
),
),
]);
}
then build your header like this:
Row(
children: [
_rightIcons(),
Expanded(
child: Center(
child: Text(
'TITLE',
style: const TextStyle(
color: Colors.white,
fontSize: 30,
fontWeight: FontWeight.w500),
),
),
),
Opacity(
opacity: 0,
child: _rightIcons(),
)
],
),
You can use centerTitle:true on Appbar
appBar: AppBar(
centerTitle: true,
title: Text("title"),
actions: [
Another way
Container(
color: Colors.purple,
height: 40 * 2,
width: MediaQuery.of(context).size.width,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
IconButton(onPressed: () {}, icon: Icon(Icons.navigate_before)),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Expanded(
flex: 1,
child: SizedBox(),
),
Expanded(
flex: 4,
child: Text(
'TITLE',
textAlign: TextAlign.center,
style: const TextStyle(
color: Colors.white,
fontSize: 30,
fontWeight: FontWeight.w500),
),
),
Expanded(
flex: 1,
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
GestureDetector(
child: Icon(Icons.wallet_membership,
color: Colors.white),
),
const SizedBox(width: 17),
GestureDetector(
onTap: () {},
child: const SizedBox(
child:
Icon(Icons.settings, color: Colors.white),
),
),
]),
),
)
],
),
],
),
)
Preferable solution:
You can implements PreferredSizeWidget to create custom Appbar. Play with color and other decoration.
class MyAppBar extends StatelessWidget implements PreferredSizeWidget {
const MyAppBar({super.key});
#override
Widget build(BuildContext context) {
return Stack(
children: [
Align(
alignment: Alignment.bottomCenter,
child: Text("title"),
),
Align(
alignment: Alignment.bottomRight,
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
IconButton(
//you can use callback method to get onpressed
onPressed: () {},
icon: Icon(Icons.settings),
),
IconButton(
onPressed: () {},
icon: Icon(Icons.settings),
),
],
),
)
],
);
}
#override
Size get preferredSize => const Size.fromHeight(kToolbarHeight * 2);
}
And use like appBar: MyAppBar(),
Folloing is my alert dialog box code, i need to set an background image for the alert dialog instead of blue color, need to show a design
AlertDialog(
backgroundColor: Colors.blue,
titlePadding: EdgeInsets.all(0),
contentPadding: EdgeInsets.all(0),
title: Container(
decoration: BoxDecoration(
color: profile_edit_toolbar_color,
borderRadius: BorderRadius.all(Radius.circular(8))),
width: MediaQuery.of(context).size.width * 0.7,
height: MediaQuery.of(context).size.height * 0.5,
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Padding(
padding: const EdgeInsets.all(18),
child: Text(
'Select countries to show',
style: TextStyle(
color: Colors.yellow[300],
fontSize: 20,
fontFamily: fontFamily_3),
// style: CustomStyle.balooCustom(20, Colors.white)
),
),
IconButton(
onPressed: () {
Navigator.of(context).pop();
},
icon: Icon(
Icons.close,
size: 25,
color: Colors.white,
)),
],
),
Row(
children: [
Expanded(
child: Container(
height: 120,
child: DisplayCountriesForm(
countriesList: eventResponse.countriesList,
num: 0,
displayCountries: displayCountries,
onValueChanged: (updatedList) {
},
),
)),
Expanded(
child: Container(
height: 120,
child: DisplayCountriesForm(
countriesList: eventResponse.countriesList,
num: 1,
displayCountries: displayCountries,
onValueChanged: (updatedList) {
},
),
)),
Expanded(
child: Container(
height: 120,
child: DisplayCountriesForm(
countriesList: eventResponse.countriesList,
num: 2,
displayCountries: displayCountries,
onValueChanged: (updatedList) {
},
),
)),
],
),
],
),
),
);
Try below code I have add background image of the alert dialog hope your problem is solved , Use your widget also and change background image on your need
TextButton(
child: Text('Pressed Me'),
onPressed: () => showDialog(
context: context,
builder: (context) => AlertDialog(
content: Stack(
alignment: Alignment.center,
children: <Widget>[
Image.network(
'https://www.kindpng.com/picc/m/355-3557482_flutter-logo-png-transparent-png.png',
),
Text(
'Add Your Text Here',
style: TextStyle(
fontSize: 24,
),
),
],
),
),
),
),
Your Result Screen->
I have the following code:
#override
Widget build(BuildContext context) {
// This method is rerun every time setState is called, for instance as done
// by the _incrementCounter method above.
//
// The Flutter framework has been optimized to make rerunning build methods
// fast, so that you can just rebuild anything that needs updating rather
// than having to individually change instances of widgets.
this.setTable();
return Scaffold(
appBar: AppBar(
// Here we take the value from the MyHomePage object that was created by
// the App.build method, and use it to set our appbar title.
title: Row(children: <Widget>[
Image.asset(
'images/logobig.png',
width: 40.0,
height: 40.0,
),
Text(widget.title),
]),
backgroundColor: Colors.blue,
),
body: SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: SingleChildScrollView(
scrollDirection: Axis.vertical,
child: Column(children: <Widget>[
Padding(
padding: const EdgeInsets.all(8.0),
child: Text(
"Currency Exchange Rates",
textScaleFactor: 1,
style: TextStyle(fontWeight: FontWeight.bold),
),
),
DataTable(
// textDirection: TextDirection.rtl,
// defaultVerticalAlignment: TableCellVerticalAlignment.bottom,
// border:TableBorder.all(width: 2.0,color: Colors.red),
showCheckboxColumn: false,
columns: const <DataColumn>[
DataColumn(
label: Text(
'Symbol',
style: TextStyle(fontWeight: FontWeight.bold),
),
),
DataColumn(
label: Text(
'Buy',
style: TextStyle(fontWeight: FontWeight.bold),
),
),
DataColumn(
label: Text(
'Sell',
style: TextStyle(fontWeight: FontWeight.bold),
),
),
],
rows: rows,
),
]),
),
),
bottomNavigationBar: Material(
color: Colors.white,
child: Row(children: <Widget>[
FlatButton(
onPressed: () => {},
color: Colors.white,
padding: EdgeInsets.all(10.0),
child: Column(
// Replace with a Row for horizontal icon + text
children: <Widget>[
ImageIcon(
AssetImage('images/dollar_world_grid_selected.png'),
size: 40.0,
),
Text(
"Currency",
style:
TextStyle(color: Color.fromRGBO(43, 73, 193, 0.4)),
)
],
)),
FlatButton(
onPressed: () => {
Navigator.pushReplacement(
context,
new MaterialPageRoute(
builder: (context) => goldRate()))
},
color: Colors.white,
padding: EdgeInsets.all(10.0),
child: Column(
// Replace with a Row for horizontal icon + text
children: <Widget>[
ImageIcon(
AssetImage('images/gold-bars.png'),
size: 40.0,
),
Text(
"Gold",
style: TextStyle(
color: Color.fromRGBO(127, 127, 127, 0.4)),
)
],
)),
])));
}
The buttomNavigationBar should navigate between different screents when the user clicks on one of the buttons.
Unfortunately I get the following output:
As you can see it is displayed up. other components not displayed and the icon images are not appearing. Any Idea on how to fix or otherway to do it? Thanks
Replace the bottomNavigationBar with persistentFooterButtons:
persistentFooterButtons: <Widget>[
new Container(
height: 100,
child: Row(
children: <Widget>[
FlatButton(
onPressed: () => {},
color: Colors.white,
padding: EdgeInsets.all(10.0),
child: Column(
// Replace with a Row for horizontal icon + text
children: <Widget>[
ImageIcon(
AssetImage('images/dollar_world_grid_selected.png'),
size: 40.0,
),
Text(
"Currency",
style:
TextStyle(color: Color.fromRGBO(43, 73, 193, 0.4)),
)
],
)),
FlatButton(
onPressed: () => {},
color: Colors.white,
padding: EdgeInsets.all(10.0),
child: Column(
// Replace with a Row for horizontal icon + text
children: <Widget>[
ImageIcon(
AssetImage('images/gold-bars.png'),
size: 40.0,
),
Text(
"Gold",
style:
TextStyle(color: Color.fromRGBO(127, 127, 127, 0.4)),
)
],
),
),
],
),
),
],
In case you want to use BottomNavigationBar, take a look at the example in the documentation.
Whenever I used FlatButton onPressed Method Is Not Working In Positioned Widget.
I am designing one screen in that buttons are always in the bottom of the screen and that button click we can move to other screens,but here it is not working, can anyone check and help me out.thaks in advance
child: Stack(
// height: MediaQuery.of(context).size.height,
children: <Widget>[
Positioned(
left: 0,
bottom: 0,
// alignment: Alignment(0, 0),
child: Row(
mainAxisSize: MainAxisSize.max,
crossAxisAlignment: CrossAxisAlignment.end,
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[
SizedBox(height: 115),
ButtonTheme(
minWidth:
MediaQuery.of(context).size.width / 2,
height: 60.0,
child: FlatButton.icon(
icon: Icon(FontAwesomeIcons.fileInvoice),
color: Colors.white,
onPressed: () {
MaterialPageRoute(builder: (context) => MainScreen());
},
label: Text(
"My Orders",
textAlign: TextAlign.center,
style: TextStyle(
// decoration: TextDecoration.underline,
fontSize: 25,
fontWeight: FontWeight.bold,
color: Theme.of(context).accentColor,
),
),
),
),
SizedBox(height: 115),
ButtonTheme(
minWidth:
MediaQuery.of(context).size.width / 2,
height: 60.0,
child: FlatButton.icon(
icon: Icon(FontAwesomeIcons.dollarSign),
color: Colors.white60,
onPressed: () {
Navigator.pushReplacementNamed(
context, '/home');
},
label: Text(
"Bean Balnace",
textAlign: TextAlign.center,
style: TextStyle(
// decoration: TextDecoration.underline,
fontWeight: FontWeight.bold,
fontSize: 20,
color: Theme.of(context).accentColor,
),
),
),
),
],
)),
Change this line:
MaterialPageRoute(builder: (context) => MainScreen());
to this:
Navigator.push(context, MaterialPageRoute(builder: (context) => MainScreen()));
I recreated your case and am able to navigate to new screen after tapping on both buttons. Here's the full code I tried:
declared /home route as:
return MaterialApp(
initialRoute: '/',
routes: {
'/home': (context) => NextScreen()
},
home: MyHomePage(),
);
Then, it's pretty much the code you shared apart from minor changes in My Orders onPressed() event:
return Scaffold(
body: Container(
child: Stack(
// height: MediaQuery.of(context).size.height,
children: <Widget>[
Positioned(
left: 0,
bottom: 0,
// alignment: Alignment(0, 0),
child: Row(
mainAxisSize: MainAxisSize.max,
crossAxisAlignment: CrossAxisAlignment.end,
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[
SizedBox(height: 115),
ButtonTheme(
minWidth:
MediaQuery.of(context).size.width / 2,
height: 60.0,
child: FlatButton.icon(
icon: Icon(Icons.forward),
color: Colors.white,
onPressed: () {
Navigator.push(context, MaterialPageRoute(builder: (context) => NextScreen()));
},
label: Text(
"My Orders",
textAlign: TextAlign.center,
style: TextStyle(
// decoration: TextDecoration.underline,
fontSize: 25,
fontWeight: FontWeight.bold,
color: Theme.of(context).accentColor,
),
),
),
),
SizedBox(height: 115),
ButtonTheme(
minWidth:
MediaQuery.of(context).size.width / 2,
height: 60.0,
child: FlatButton.icon(
icon: Icon(Icons.business),
color: Colors.white60,
onPressed: () {
Navigator.pushReplacementNamed(
context, '/home');
},
label: Text(
"Bean Balnace",
textAlign: TextAlign.center,
style: TextStyle(
// decoration: TextDecoration.underline,
fontWeight: FontWeight.bold,
fontSize: 20,
color: Theme.of(context).accentColor,
),
),
),
),
],
)),
]
)
)
);
NextScreen class:
class NextScreen extends StatelessWidget {
#override
Widget build(BuildContext context) {
// TODO: implement build
return Scaffold(
appBar: AppBar(
title: Text('Test'),
),
);
}
}
Hope this helps.
Try to put your widget as last widget of Stack widget children.
Im trying to use onTap in Inkwell to open/preview an existing Card but unsure how to do this, for now I just have it printing 'hello'
body: Container(
color: Colors.indigo,
child: Column(
children: <Widget>[
Flexible(
child: FirebaseAnimatedList(
query: databaseReference,
itemBuilder: (
_, DataSnapshot snapshot,
Animation<double> animation, int index) {
return Card(
child: Padding(
padding: const EdgeInsets.all(10.0),
child: InkWell(
child: ListTile(
title: Text(
boardMessages[index].subject,
style: TextStyle(fontWeight: FontWeight.bold
),),
),
onTap: (){
print('hello');
},
),
),
);
},
),
),
],
),
EDIT: I know how to do it using Full Screen Page thanks to the docs provided, how would I do this with a Dialog? Much appreciated
Over your onTap drawer item do this:
onTap: () {
Navigator.pop(context);
_showDialog(text: 'Index $index');
}
And use the following code to show a Dialog with the necessary text:
void _showDialog({#required String text}) {
showDialog(
context: context,
barrierDismissible: false,
builder: (context) {
return Dialog(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(4),
),
elevation: 0,
child: Padding(
padding: EdgeInsets.symmetric(
horizontal: 20,
vertical: 10,
),
child: IntrinsicWidth(
child: IntrinsicHeight(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
SizedBox(
height: 10,
),
Text(
"Custom Alert Dialog",
style: TextStyle(
fontWeight: FontWeight.w700,
fontSize: 18,
),
),
SizedBox(
height: 20,
),
Text(
text,
style: TextStyle(
fontWeight: FontWeight.w400,
fontSize: 16,
),
),
SizedBox(
height: 20,
),
Align(
alignment: Alignment.bottomRight,
child: FlatButton(
onPressed: () {
Navigator.pop(context);
},
child: Text("OK"),
),
),
],
),
),
),
),
);
},
);
If fully customizable with any needs you'd had.