arranging a scaffold with buttons - flutter

i wrote this code in flutter and i wanna know if i can make it better,
i did a lot of "work around" that i feel there's a better way to write it.
especially the buttons with the expanded between them, and the sizedbox.
the screen has text in the middle(getVerse), and and two buttons, one is bottom left and the other is bottom right.
the first expanded separate the text from the buttons, and the second expanded is to separate the two buttons
help is appreciated and thanks for your time.
Scaffold(
appBar: AppBar(
title: Text(
suras.elementAt(widget.index),
textAlign: TextAlign.right,
),
),
body: Column(
children: [
SizedBox(
height: 100,
),
Padding(
padding: const EdgeInsets.all(8.0),
child: Text(
getVerse(widget.index + 1, currentVerse),
textAlign: TextAlign.center,
style: TextStyle(
color: Colors.white,
fontWeight: FontWeight.bold,
fontSize: 24,
fontFamily: 'KFGQPC BAZZI Uthmanic Script',
),
),
),
Expanded(child: Container()),
Row(
children: [
ElevatedButton(
onPressed: () {
setState(() {
currentVerse++;
});
},
child: Text('not sure'),
),
Expanded(child: Container()),
ElevatedButton(
onPressed: null,
child: Text('sure'),
),
],
),
],
),
);

If you want that those 2 buttons to stay at the bottom you can use floatingActionButton in the Scaffold property. You can change the location of those buttons with the floatingActionButtonLocation.
Scaffold(
appBar: AppBar(
title: Text('MyApp'),
),
floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,
floatingActionButton: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
ElevatedButton(
onPressed: () {},
child: Text('Not sure'),
),
ElevatedButton(
onPressed: () {},
child: Text('Sure'),
)
],
),
body: Padding(
padding: const EdgeInsets.all(8.0),
child: Text(
'My Text',
textAlign: TextAlign.center,
),
),
),

Related

I want to right justify the TextButton in Flutter

I want to send the "See More" button in the middle to the right.
Row(
children: <Widget>[
Stack(
children: const <Widget>[
Align(
alignment: Alignment.topLeft,
child: Padding(
padding: EdgeInsets.all(8.0),
child: Text(
'Your Watchlist',
style: TextStyle(
color: Colors.white,
fontSize: 20,
fontWeight: FontWeight.bold,
),
),
),
),
],
),
TextButton(
child: const Text(
'See More >>',
style: TextStyle(color: Colors.yellow, fontSize: 16),
),
onPressed: () {
Navigator.of(context).push(MaterialPageRoute(
builder: (context) => movie_list(),
));
},
),
],
),
Also, how can I pull data from firebase to listview items in the form of cards at the bottom, can you suggest a source on this subject?
You can achieve this by 2 methods
Option1
Add
mainAxisAlignment: MainAxisAlignment.spaceBetween,
To the row widget
Or
Option2
add
Spacer()
Between the see more and the stack widget
You can include Spacer() on middle portion,
Row
- WidgetA
- Spacer()
- WidgetB

Why Third Row widget in the Column stack goes away?

I am building the app where my widget tree starts with Scaffold and as for body parameter, I assign the column widget. Within the column widget, I want the first 3 buttons sitting side by side, which work fine and next Expanded Widget which takes whole screen and third again 2 buttons sitting side by side. However, the thing is that, the third row widget is not visible on the screen of the phone. Can someone explain why it happens?
Scaffold(
appBar: AppBar(
title: const Text("My Work Timer"),
),
body: Column(
mainAxisSize: MainAxisSize.min,
children: [
Row(
children: [
Padding(padding: EdgeInsets.all(defaultPadding)),
Expanded(
child: ProductivityButton(
color: const Color(0xff009688),
text: "Work",
size: 3,
onPressed: () {}),
),
Padding(padding: EdgeInsets.all(defaultPadding)),
Expanded(
child: ProductivityButton(
color: const Color(0xff607D8B),
text: "Short Break",
size: 3,
onPressed: () {}),
),
Padding(padding: EdgeInsets.all(defaultPadding)),
Expanded(
child: ProductivityButton(
color: const Color(0xff455A64),
text: "Long Break",
size: 3,
onPressed: () {}),
),
Padding(padding: EdgeInsets.all(defaultPadding)),
],
),
Expanded(
child: Text("Hello"),
),
Row(
children: [
Padding(padding: EdgeInsets.all(defaultPadding)),
Expanded(
child: ProductivityButton(
color: const Color(0xff212121),
size: 2,
text: "Stop",
onPressed: () {},
)),
Padding(padding: EdgeInsets.all(defaultPadding)),
Expanded(
child: ProductivityButton(
color: const Color(0xff009688),
size: 2,
text: "Restart",
onPressed: () {},
)),
Padding(padding: EdgeInsets.all(defaultPadding)),
],
)
],
),
);
regards

Centered Text inside a button with an icon in Flutter

I'm having issues where I want to make a button (any kind to achieve this) that has an icon that is always in the same position at the start of the button, and that the text of the button is always centered compared to the text below it and always centered in the button itself, even if the text is dynamic. This is what I want to achieve:
The button text is centered according to the text below(that stays the same) and it is centered with the above button, but if the button text changes dynamically, then I have these issues:
Or like this one:
Any ideas how to solve this problem?
I tried with the Expanded widget and adding the flex properties but failed. I tried some other stuff too but failed also... Here is the button code:
TextButton(
style: ButtonStyle(
backgroundColor:
MaterialStateProperty.all(Colors.blue)),
onPressed: () {},
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
Expanded(
flex: 1,
child: Icon(
Icons.keyboard_arrow_right_sharp,
color: Colors.white,
),
),
Expanded(
flex: 4,
child: Center(
child: Text(
"SOME TEXT",
style: TextStyle(color: Colors.white),
),
),
)
],
),
),
Thanks in advance for your help!
There are a couple of options to do that. I'm going to assume the size of the text could change so you want a flexible solution.
The first option is the most obvious of the two, but will break if the text is too long. The trick is to add an empty sizedBox at the end of the button, so the text can be centered in an expanded widget.
TextButton(
style: ButtonStyle(
backgroundColor: MaterialStateProperty.all(Colors.blue),
),
onPressed: () {},
child: Row(
children: [
Icon(
Icons.keyboard_arrow_right_sharp,
color: Colors.white,
size: 24,
),
Expanded(
child: Center(
child: Text(
"SOME TEXT",
style: TextStyle(
color:Colors.white,
),
),
),
),
SizedBox(
width: 24, // width of the icon
),
],
),
);
The other option is using a stack widget. This way, if the text is too long it will overlap with the icon but it's less probable that it will overflow the button.
TextButton(
style: ButtonStyle(
backgroundColor: MaterialStateProperty.all(Colors.blue),
),
onPressed: () {},
child: Stack(
children: [
Positioned(
left: 0,
child: Icon(
Icons.keyboard_arrow_right_sharp,
color: Colors.white,
size: 24,
),
),
Center(
child: Text(
"SOME TEXT",
style: TextStyle(
color:Colors.white,
),
),
),
],
),
);
Let's discuss about you code :
using row with a mainaxisalignment from start make the element start from the available area. then i suggest to use the SizedBox to make some of spacing between the elements as you want and play with the width of it.
TextButton(
style: ButtonStyle(
backgroundColor:
MaterialStateProperty.all(Colors.blue)),
onPressed: () {},
child: Row(
mainAxisAlignment: MainAxisAlignment.start, // here the issue
children: [
Expanded(
flex: 1,
child: Icon(
Icons.keyboard_arrow_right_sharp,
color: Colors.white,
),
),
SizedBox(width: MediaQuery.of(context).size.width * 0.08, // change this value as you want 0.08 or 0.1 ...etc
),
Expanded(
flex: 4,
child: Center(
child: Text(
"SOME TEXT",
style: TextStyle(color: Colors.white),
),
),
)
],
),
),
for more read this documentation

Adding multiple rows or column in body

Hi trying to figure out why my hamburger is getting misaligned when i add another Expanded() code within the body.
I tried to follow this url to develop a hamburger menu and responsive for all platforms at once.
Flutter Blog
Below is the code that i tried where i added Expanded() below the Row()
final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();
#override
Widget build(BuildContext context) {
final width = MediaQuery.of(context).size.width;
return Scaffold(
key: _scaffoldKey,
drawer: AppDrawer(),
body: Row(
children: [
Row(
children: [
Padding(
padding: const EdgeInsets.all(16),
child: IconButton(
icon: Icon(Icons.menu, size: 30),
onPressed: () {
_scaffoldKey.currentState.openDrawer();
}),
),
],
),
Expanded(
child: Container(
width: width,
child: Column(
children: [
Expanded(
child: Lottie.network(
'https://assets2.lottiefiles.com/datafiles/6WfDdm3ooQTEs1L/data.json'),
),
Expanded(
child: Column(
children: [
Flexible(
child: Text(
"Multivariate Testing",
style: GoogleFonts.montserrat(
fontSize: 50,
),
),
),
SizedBox(
height: 10,
),
Flexible(
child: Text(
'Run experiments to make key flows more effective.',
style: GoogleFonts.montserrat(
fontSize: 25,
),
),
),
SizedBox(
height: 35,
),
// ignore: deprecated_member_use
TextButton(
onPressed: () {},
child: Text(
'Create Experiment',
style: GoogleFonts.montserrat(
fontSize: 20,
),
),
)
],
),
),
],
),
),
)
],
),
);
}
}
and the output that i am seeing from mobile view. Appreciate any help. Sorry for too big screenshot!
This is because of the default functionality of Row.
So change your first child for your top level Row to this,
Scaffold(
key: _scaffoldKey,
drawer: AppDrawer(),
body: Row(
children: [
Align(
alignment: Alignment.topCenter,
child: Padding(
padding: const EdgeInsets.all(16),
child: IconButton(
icon: Icon(Icons.menu, size: 30),
onPressed: () {
_scaffoldKey.currentState.openDrawer();
})),
),
Expanded( ...... rest of your code
Here, we are using the Align widget with alignment: Alignment.topCenter.
Align widget takes the entire available space in the parent and then depending on the alignment property, aligns it't child inside it.
So, saying Alignment.topCenter will place it at the top vertically and middle horizontally.
Using an AppBar will unnecessarily complicate your situation since now, the AppBar is going to take up space a the top, but in your case, you want your Lottie view to be visible at the top, so it will overlap.
Because Expanded fills up the whole space and that's why your hamburger is getting misaligned.
Why don't you try using appbar for the hamburger?

How to center AlertDialog FlatButton in Flutter

How can I style the FlatButton to be aligned on center without having to create a custom AlertDialog?
AlertDialog(
title: Text(
'Alert Dialog'.toUpperCase(),
textAlign: TextAlign.center,
style: TextStyle(fontWeight: FontWeight.bold, fontSize: 28.0),
),
content: SingleChildScrollView(
child: ListBody(
children: <Widget>[
Text('Scrollable AlertDialog' * 100),
],
),
),
actions: <Widget>[
FlatButton(
child: Text(
'Accept'.toUpperCase(),
),
onPressed: () {
Navigator.of(context).pop();
},
),
],
);
This is how it looks like
I tried removing 'actions' and adding the FlatButton inside a row in 'content', but the scroll stopped working and the content overflowed.
content: Column(
children: <Widget>[
SingleChildScrollView(
child: ListBody(
children: <Widget>[
Text('Scrollable AlertDialog.' * 50),
],
),
),
Row(
children: <Widget>[
FlatButton(
child: Text(
'Accept'.toUpperCase(),
style: TextStyle(
color: Theme.of(context).primaryColor,
fontWeight: FontWeight.bold,
fontSize: 16.0
),
),
onPressed: () {
Navigator.of(context).pop();
},
),
],
),
],
),
Google's material design guidelines don't want you to place that in center, which is why Flutter team used ButtonBar for actions and you have no control over ButtonBar's alignment inside actions property, so if you really want to center your single button, there are 2 simple workarounds:
Make changes in source code, in dialog.dart's AlertDialog's build method, you'll see a ButtonBar, widget, add alignment to it.
ButtonBar(
alignment: MainAxisAlignment.center, // add this line
// ...
)
You can use dummy widgets like SizedBox and provide some width to it.
actions: [
SizedBox(width: space),
FlatButton(
onPressed: () {},
child: Text('Button'),
),
SizedBox(width: space),
]
Screenshot:
Try to play around with actionsPadding which is one of the property of AlertDialog.
final horizontalPadding=50;
horizontal padding is the one that is transparent to the left and right of the dialog.
actionsPadding: EdgeInsets.only(right: MediaQuery.of(context).size.width/2-horizontalPadding*2),
Also, go through How to style AlertDialog Actions in Flutter . You can change and play around within the library as mentioned here. But, this may not work for your colleagues who are sharing the git repo. They will have to update their libraries as well in their local machines.
actions: <Widget>[
Align(
alignment: Alignment.center,
child: ElevatedButton(
onPressed: () {
//your logic
Navigator.pop(context);
},
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Text('Close'),
),
),
),
],
Just use actionsAlignment property in AlertDialog Widget.
AlertDialog(
actions: ...,
actionsAlignment: MainAxisAlignment.spaceBetween
)