how to center FloatingActionButton inside the persistentFooterButtons - flutter

Can someone explain to me how can i center the FloatingActionButton inside the persistentFooterButtons. im missing something here.
List _footer() {
return <Widget>[
new ButtonBar(
children: <Widget>[
new Container(
child: new Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
new FloatingActionButton(
backgroundColor: Colors.redAccent,
onPressed: () => {},
),
],
),
)
],
)
];}
===
#override Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text("Question"),
),
body: _body(),
persistentFooterButtons: _footer(),
); }

I looked at the code of Scaffold, below is how persistentFooterButtons created:
new Container(
decoration: new BoxDecoration(
border: new Border(
top: Divider.createBorderSide(context, width: 1.0),
),
),
child: new SafeArea(
child: new ButtonTheme.bar(
child: new SafeArea(
top: false,
child: new ButtonBar(
children: widget.persistentFooterButtons
),
),
),
),
)
You can see here, your buttons are wrapped by a ButtonBar. Now let's look at the ButtonBar code below, the DEFAULT alignment is MainAxisAlignment.end. I guess this follows the Material guidelines.
const ButtonBar({
Key key,
this.alignment: MainAxisAlignment.end,
this.mainAxisSize: MainAxisSize.max,
this.children: const <Widget>[],
}) : super(key: key);
The Flutter framework is being updated, but till today (2018 June 08th), you can not put the buttons to the center using persistentFooterButtons.
Solution: I suggest you follow my answer here to put your buttons at the center-bottom of the screen.

I found an easy solution is to wrap the FloatingActionButton in a sized box that is the same width as the screen.
persistentFooterButtons: <Widget>[
SizedBox(
width: MediaQuery.of(context).size.width,
child: FloatingActionButton(
onPressed: () {
print('Close pressed');
},
child: Text('Close'),
)
)
],

I have the same problem. I achieved the desired result with this:
persistentFooterButtons: [
Container(
width: MediaQuery.of(context).copyWith().size.width,
child: Row(
children: [
Expanded(
child: FlatButton(
child: Text('Your centered button'),
onPressed: (){},
),
)
],
),
)
]
I've used a flatbutton just as example but it works as well with floatinActionButtons.
Hope it helps

Found yet another solution. MaterialTheme (theme_data.dart) has buttonBarTheme attribute. You can modify it like following:
var myTheme = ThemeData(
buttonBarTheme: ButtonBarThemeData(
alignment: MainAxisAlignment.center,
mainAxisSize: MainAxisSize.max,
),
)
And specify it in your MaterialApp widget:
MaterialApp(theme: myTheme)

For anyone trying something similar, but instead of a FloatingActionButton, a set of, let's say two ElevatedButtons, you can center them like this:
...
persistentFooterButtons: [
Center(
child: Column(
children: [
ElevatedButton(), //Button 1
SizedBox(),
ElevatedButton(), //Button 2
],
),
),
],
...
In hope that anyone might find it useful in the future.

floatingActionButton can be aligned or positioned by making use of floatingActionButtonLocation property, however it is not useful for button placed inside persistentFooterButtons.
The persistentFooterButtons are wrapped inside ButtonBar and we don't have any way to override the ButtonBar default alignment of MainAxisAlignment.end for persistentFooterButtons.
Flutter team could have provided persistentFooterButtonsAlignment property but without it, one can achieve similar layout using following bottomNavigationBar hack, if it is not already being used for something else.
bottomNavigationBar: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Divider(
height: 0,
),
Padding(
padding: const EdgeInsets.all(8.0),
child: FlatButton(
child: Text('Button'),
color: Theme.of(context).primaryColor,
materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
padding: EdgeInsets.symmetric(horizontal: 16.0, vertical: 12.0),
textColor: Theme.of(context).colorScheme.background,
onPressed: () {},
),
),
],
),

Related

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?

Flutter - FlatButton Fill available horizontal space

I'm trying to have a UI in such a way that the number of buttons in a row changes depending on available information. More specifically, there will always be one FlatButton that links to an external page, but if a download link is also provided, then there will be a second FlatButton in the row.
On the website that currently exists, we have this working for one button versus two buttons, but I can't get the one button to horizontally expand to fill the available space.
At the moment, I add the FlatButtons to a List<Widget> variable that I pass as the children for a row. I have tried using Flex -> Expanded, SizedBox.expand, CrossAxisAlignment.stretch and every solution I have found on this site so far to get it to expand, but every solution I have tried have all resulted in forced infinite width or unbounded width or non-zero flex but incoming width constraints are unbounded.
Here's my code in the build method as it currently stands:
List<Widget> fullTextDownloadBtns = new List();
if (this.fullArticleUrl != null && this.fullArticleUrl.isNotEmpty) {
fullTextDownloadBtns.add(
FlatButton(
color: Color(0x66629c44),
onPressed: _openFullArticle,
child: Text(
"Full Article",
style: TextStyle(color: Color(0xff629c44)),
),
)
);
}
if (this.downloadUrl != null && this.downloadUrl.isNotEmpty) {
fullTextDownloadBtns.add(
FlatButton(
color: Color(0x664d69b1),
onPressed: _download,
child: Text(
"Download",
style: TextStyle(color: Color(0xff4d69b1)),
),
)
);
}
return Scaffold(
appBar: AppBar(
backgroundColor: Color(0xff0096b0)
),
body: SingleChildScrollView(
scrollDirection: Axis.vertical,
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
// ...related image, title
Container(
padding: EdgeInsets.all(15.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: fullTextDownloadBtns,
),
), // Read full article & download PDF
// ... Authors, excerpt/description, like/share buttons, comments
],
)
),
);
Wrapping your buttons with Expanded is the way to go here (I tried it with your code) :
Row(
children: [
Expanded(
child: FlatButton(onPressed: (){},
child: Text("1")),
),
Expanded(
child: FlatButton(onPressed: (){},
child: Text("2")),
)
],
),
By the way, since the SDK 2.2.2 (in your pubspec.yaml), you can use conditions within the children list :
children: [
if(true == true)
FlatButton(
onPressed: (){},
child: Text("1")),
],
I just wanted to add that you can adjust the width of the buttons border by using the 'width' property inside 'side: BorderSide(color: Colors.black54, width: 2.2)'.
Row(
children: <Widget>[
Expanded(
child: FlatButton(
onPressed: () {},
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(5.0),
side: BorderSide(color: Colors.black54, width: 2.2),
),
color: Colors.white,
child: (Text('BUTTON NAME')),
),
),
],
),
Couldn't find how to change the border outline width for a long while on here. So thought I might add it here. Maybe help some other noobie like me in the future.
You can use a Row widget and use two Expanded widget which their child are FlatButton.implement the condition fot them seperately sth like:
Row(
children:[
trueCondition ? Expanded(
child: FlatButton()
) : SizedBox()
]
)

How to align a widget to the right of a dynamic centered widget in Flutter?

I have a text widget in the center that has a dynamic width. However, I want to add in a widget to the right of this text widget.
Because this center text wiget has a dynamic width, I cannot use absolute positioning widgets such as Align or the Position Widget. I am looking for something similar to RelativeLayout in Android.
Widget body() {
return Container(
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text('Center text'),
FlatButton(
child: Text('next'),
onPressed: () {},
),
],
),
);
}
With #Igors method I can end with a center widget with a button on each end evenly spaced. I am aiming for the button to be to the right of.
Widget body() {
return Container(
child: Row(
children: <Widget>[
Expanded(
child: FlatButton(
child: Text('next'),
onPressed: () {},
),
),
Container(color: Colors.red, child: Text('test')),
Expanded(
child: FlatButton(
child: Text('next'),
onPressed: () {},
),
),
],
),
);
}
Edit: Solved through the use of Sized Box on each side of the centered widget 1.
Row(
children: <Widget>[
Expanded(
child: Container(
color: Colors.green
),
),
Container(
color: Colors.red,
child: Text('test')
),
Expanded(
child: Container(
color: Colors.blue
),
),
],
)
Use the Widget Row and add the text widget in a Container Widget.
And add margin for the Container

Flutter, how to get rid of raisedButton bottom margin?

So I'm trying to remove the bottom margin of raisedButton so it will look like it is merged with the card below it.
here's what it looks like
here is my code
Expanded(
child: Card(
elevation: 5,
// shape:
// RoundedRectangleBorder(borderRadius: BorderRadius.circular(22)),
child: Column(
children: <Widget>[
Row(
children: <Widget>[
Padding(
padding: const EdgeInsets.all(8.0),
child: Text("Apakah anak sudah bisa ... ?",
style: TextStyle(fontWeight: FontWeight.bold)),
),
],
),
Row(
children: <Widget>[
Expanded(
child: RaisedButton(
child: Text(
"Iya",
style: TextStyle(color: Colors.white),
),
color: Colors.green[300],
onPressed: () {}),
),
Expanded(
child: RaisedButton(
child: Text(
"Tidak",
style: TextStyle(color: Colors.white),
),
color: Colors.red[200],
onPressed: () {}))
],
)
],
),
),
)
or do you guys have any other alternative solution to achieve that?
You can explicitly set your Row height to match the height of your RaisedButton. Simply wrap it inside a Container and add the height attribute.
If you want to, you can access the default height by using Theme.of(context).buttonTheme.height. Theme.of returns the ThemeData used in the current context.
Here a minimal example:
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: Center(
child: Container(
child: Card(
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Text('Test'),
Container(
height: Theme.of(context).buttonTheme.height,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
RaisedButton(
onPressed: () {},
child: Text('Yes'),
color: Colors.green,
),
RaisedButton(
onPressed: (){},
child: Text('No'),
color: Colors.red,
)
],
),
),
],
)
),
),
)),
);
}
}
I had the same problem. NikasPor's answer didnt work for me, unfortunately. The way I fixed it is by seeting the crossAxisAlignment on the row to .stretch
Row(
crossAxisAlignment: CrossAxisAlignment.stretch,
children:[ /* Buttons Here */]
)

When keyboard is shown, everything is pushed up and I get a error

I have the following code:
class _MyHomePageState extends State {
#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.
return new Scaffold(
body: new Column(
children: [
new Container(
color: JBTheme.colorGreenBrand,
height: 130.0,
alignment: Alignment.bottomLeft,
child: new Center(
child: new Align(
alignment: Alignment.bottomCenter,
child: new Container(
color: JBTheme.colorOrange,
constraints: new BoxConstraints(maxWidth: 270.0),
child: new Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
new Column(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.center,
children: [
new Image.asset("flags/flag_dk.png"),
new Container(
margin: const EdgeInsets.only(top: 4.0, bottom: 4.0),
child: new Text("Danmark"),
),
new Text("DKK")
],
),
new Expanded(child: new Image.asset("images/arrow.png")),
new Column(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.center,
children: [
new Image.asset("flags/flag_us.png"),
new Container(
margin: const EdgeInsets.only(top: 4.0, bottom: 4.0),
child: new Text("USA"),
),
new Text("USD")
],
)
],
),
),
),
),
),
new Expanded(
child: new Container(
color: JBTheme.colorGreyMedium,
child: new Column(
children: [
new Expanded(child: new Container()),
new Padding(
padding: const EdgeInsets.only(bottom: 8.0),
child: new Card(
elevation: -8.0,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(15.0),
),
child: new Container(
width: 200.0,
height: 30.0,
color: JBTheme.colorWhite,
child: new Stack(
children: [
new TextField(
textAlign: TextAlign.center
)
],
)
),
)
)
],
),
)),
new Container(
height: 260.0,
color: JBTheme.colorGreenMint,
)
],
));
}
}
And it looks like this:
But when I click the TextField and the keyboard opens I get this:
I did not expect all of my layout to be moved up by the full keyboard height, I would like it to only move up enough so that the focused TextField is visible (and not to give a error). How can I fix this, and why is it happening?
Thank you
Søren
There are two solutions to this problem.
Add resizeToAvoidBottomPadding: false to your Scaffold
Scaffold(
resizeToAvoidBottomPadding: false,
body: ...)
Put your Scaffold body inside a scrollableView (like SingleChildScrollView or ListView)
new Scaffold(
body: SingleChildScrollView(child: //your existing body
...)
You can find similar problem and answer here
This is Flutters way of showing us how many pixels of content will be hidden from users eyesight when using the keypad. Try setting resizeToAvoidBottomPadding to false... From docs:
Whether the body (and other floating widgets) should size themselves
to avoid the window's bottom padding.
Scaffold(
resizeToAvoidBottomPadding: false,
This will avoid the resizing so you will at least avoid the dev warning being shown. But remember user will not see some content, and also this is a developer warning.
Update on 17/10/2019
resizeToAvoidBottomPadding is now Deprecated.
Use resizeToAvoidBottomInset to specify if the body should resize when the keyboard appears.
Scaffold(
resizeToAvoidBottomInset: false,
If you just use SingleChildScrollView content looses vertical alignment. You can also wrap the SingleChildScrollView in a Center Widget.
child: Center(
child: SingleChildScrollView(
child: Column(
children: <Widget>...
A full description of this error and two possible solutions can be found on Medium article available on https://medium.com/zipper-studios/the-keyboard-causes-the-bottom-overflowed-error-5da150a1c660. The last one works great for me.