How to align a widget to the right of a dynamic centered widget in Flutter? - 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

Related

How to Locate the Text() center when using expanded(flex:)?

Please see my code and scree shot below. I want locate Text("to be center") at center horizontally, but comparatively located right side as showen below.
I understand i'ts because I'm using expanded widget and set flex 1 & 4 and Text("to be center") are inclueded in latter block.
How can I located totally or relatively center but using expandede & flex property like this case ?
Also I understand I can adjust it by wrapping Text() with padding and set EdgeInsets.only(right:X) but I can not figure out if it is totally cenerized or not...
Row(
children: [
Expanded(
flex:1,
child:TextButton(
style: TextButton.styleFrom(
alignment: Alignment.centerLeft,
),
child: const Icon(
Icons.close,
color: MyStyle.textColor,
),
onPressed: () {
Navigator.of(context).pop();
},
),
),
Expanded(
flex:4,
child: Container(
alignment: Alignment.center,
decoration: const BoxDecoration(
),
child: Text("to be center",style: MyText(myFontSize: 15).style()),
)
),
],
),
Just use Spacer at the end inside Row
Row(
children: [
Expanded(
flex: 1,
child: TextButton(
style: TextButton.styleFrom(
alignment: Alignment.centerLeft,
),
child: const Icon(
Icons.close,
color: MyStyle.textColor,
),
onPressed: () {
Navigator.of(context).pop();
},
),
),
Expanded(
flex: 4,
child: Container(
alignment: Alignment.center,
decoration: const BoxDecoration(),
child: Text(
"to be center",
style: MyText(myFontSize: 15).style(),
),
),
),
// like this
const Spacer(),
],
),
Learn more about the Spacer widget
Try below code: refer layout
Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Expanded(
child: TextButton(
style: TextButton.styleFrom(
alignment: Alignment.centerLeft,
),
child: const Icon(
Icons.close,
),
onPressed: () {
Navigator.of(context).pop();
},
),
),
const Expanded(
child: Center(
child: Text(
'to be center',
),
),
),
const Expanded(child: SizedBox())
],
),
Result->
The simple solutions could be:
Use textAlign attribute of Text widget or
Wrap Text widget with Center widget inside Expanded widget or
You can even explore the widget IntrinsicWidth with Center widget.

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?

Incorrect use of ParentDataWidget - Row and container

I am trying to build a container with a row. In this row, I would like to have 4 icons.
If I have done it, my problem is that I am getting an error "Incorrect use of ParentDataWidget".
I do not find where the problem is coming from. If you could help me to solve this it would be appreciated. Many thanks.
Card(
child:
Container(
// color: Colors.red,
alignment: Alignment.center,
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children:[
//Time
FlatButton(
child:
InkWell(
child: Container(
// color: Colors.white,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(Icons.timer),
Text('Time'),
],
)
),
onTap: () {
print("Tapped on Time");
},
),
),
//Energy
FlatButton(
child:
InkWell(
child: Expanded(
child: Container(
// color: Colors.white,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(Icons.battery_charging_full),
Text('Energy'),
],
)
),
),
onTap: () { },
),
),
//Important
FlatButton(
child:
InkWell(
child: Expanded(
child: Container(
// color: Colors.white,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
isImportant =="true" ? Icon(Icons.star,color: Colors.orange,) :
Icon(Icons.star_border, color: Colors.grey,),
// Icon(Icons.battery_charging_full),
Text('Important'),
],
)
),
),
onTap: () {
setState(() {
if (isImportant=='true'){
isImportant = 'false';}
else
{isImportant= 'true';
}
});
},
),
),
//Urgent
FlatButton(
child:
InkWell(
child: Expanded(
child: Container(
// color: Colors.white,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
isUrgent =="true" ? Icon(Icons.flag,color: Colors.red,) :
Icon(Icons.outlined_flag, color: Colors.grey,),
// Icon(Icons.battery_charging_full),
Text('Urgent'),
],
)
),
),
onTap: () {
setState(() {
if (isUrgent=='true'){
isUrgent = 'false';}
else
{isUrgent= 'true';
}
});
},
),
),
],
),
)),
You are using Expanded widget where it cannot be used. The parent of an Expanded widget can only be a Flex widget. Expanded widget has to be a child of Row, Column or Flex widget.
Therefore you will have to remove Expanded widget from all places where the parent of Expanded Widget is not either a Row, Column or Flex. For example in the code below, Expanded widget is a child of FlatButton so you will have to remove the Expanded from here.
FlatButton(
child:
InkWell(
>>>>>>>>> child: Expanded( <<<<< REMOVE FROM HERE
child: Container(
// color: Colors.white,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(Icons.battery_charging_full),
Text('Energy'),
],
)
),
),
onTap: () { },
),
),
Please refer to Flutter docs : Expanded class
Expanded
A widget that expands a child of a Row, Column, or Flex so that the
child fills the available space.
Using an Expanded widget makes a child of a Row, Column, or Flex
expand to fill the available space along the main axis (e.g.,
horizontally for a Row or vertically for a Column). If multiple
children are expanded, the available space is divided among them
according to the flex factor.
An Expanded widget must be a descendant of a Row, Column, or Flex, and
the path from the Expanded widget to its enclosing Row, Column, or
Flex must contain only StatelessWidgets or StatefulWidgets (not other
kinds of widgets, like RenderObjectWidgets).

How can I have two buttons in the bottom using align widget inside the center and column widgets?

I am trying to have a grouped button with two individuals and place them in the bottom. It is a login screen so there are other things.
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.transparent,
body: SafeArea(
child: Center(
child: Column(
children: <Widget>[
SizedBox(
height: 75.0,
),
Text('Login'),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
RaisedButton(
color: Colors.orange,
onPressed: () {
print('login');
},
),
RaisedButton(
onPressed: () {
print('signup');
},
),
],
),
],
),
),
),
);
}
}
I've been trying with like align bottom and stuffs. But with Row(), it does not work with Center + Column widget. How can I send these two buttons to the bottom of the Center widget?
There are multiple ways to do this. One of them is to use the Spacer widget:
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.transparent,
body: SafeArea(
child: Center(
child: Column(
children: <Widget>[
SizedBox(
height: 75.0,
),
Spacer(),
Text('Login'),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
RaisedButton(
color: Colors.orange,
onPressed: () {
print('login');
},
),
RaisedButton(
onPressed: () {
print('signup');
},
),
],
),
],
),
),
),
);
Another one would be to reverse the column and start from the bottom, but most probably the side effects are not wanted.
Also, one option would be to divide the whole screen into fixed height partitions with the help of MediaQuery.of(context).size.height value so that your buttons are always at the bottom.
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.transparent,
body: SafeArea(
child: Center(
child: Column(
children: <Widget>[
SizedBox(
height: 75.0,
),
Text('Login'),
Expanded(
child:Container
(
alignment: Alignment.bottomCenter,
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
RaisedButton(
color: Colors.orange,
onPressed: () {
print('login');
},
),
RaisedButton(
onPressed: () {
print('signup');
},
),
],
),
)
)
],
),
),
),
);
}

how to center FloatingActionButton inside the persistentFooterButtons

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: () {},
),
),
],
),