Force widgets in column to match largest - flutter

I have several RaisedButton widgets inside of a column, and they have different widths based on their texts. I would like them to be the same width, but I do not want to set a static width, as it should be able to respond to changes in language and screen size/shape. The smaller widget should be resized to match the width of the largest widget in the column. What is the best way to go about doing this?
Thanks!
Column(
children: <Widget>[
RaisedButton(
child: Text("Btn1"),
onPressed: (){},
),
RaisedButton(
child: Text("LongerBtn2"),
color: Colors.Red,
onPressed: (){},
)
],
),

Could do this:
IntrinsicWidth( // <- Sizes its child's width to the child's maximum intrinsic width
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch, // <- all children will try to take as much space as possible
children: <Widget>[
RaisedButton(
child: Text("Btfffffff fsdfds dsfsa n1"),
color: Colors.green,
onPressed: () {},
),
RaisedButton(
child: Text("LongerBtn2"),
color: Colors.red,
onPressed: () {},
)
],
),
)

Related

How do I make Flutter table stretch vertically

I am new to Flutter and I cannot make my table take all the available space vertically.
Here is the code:
home: Scaffold(appBar: AppBar(),
body: Table(
children: [
TableRow(
children: [
TextButton(onPressed: () {}, child: Text('1')),
TextButton(onPressed: () {}, child: Text('2')),
]
)
]
)
)
This is what I see right now:
Filling the space vertically is not as straight forward and not a default behaviour as it is for the horizontal part. It's because you usually don't want that behaviour: most of the time you want the content itself to determine the space vertically and make a view scrollable if it's too much content (and therefore not enough space available). There are also cases for horizontally scrollable elements, but thats special behaviour then.
If you insist on forcing to fill the space vertically, you need to do that manually. In this case, you have to determine the available space and set the heights of your elements. Best way to determine the available space is making use of the LayoutBuilder widget which gives you that information and updates its subtree if this information changes (since it's a builder widget).
Here you can see a rough and simplified solution using this approach and your example (I enabled the borders so its also visible:
LayoutBuilder(
builder: (context, constraints) => Table(
border: TableBorder.all(),
children: [
TableRow(
children: [
SizedBox(
height: constraints.maxHeight / 2,
child: Align(
child: ElevatedButton(
onPressed: () {},
child: Text('1'),
),
),
),
SizedBox(
height: constraints.maxHeight / 2,
child: Align(
child: ElevatedButton(
onPressed: () {},
child: Text('2'),
),
),
),
],
),
TableRow(
children: [
SizedBox(
height: constraints.maxHeight / 2,
child: Align(
child: ElevatedButton(
onPressed: () {},
child: Text('3'),
),
),
),
SizedBox(
height: constraints.maxHeight / 2,
child: Align(
child: ElevatedButton(
onPressed: () {},
child: Text('4'),
),
),
),
],
),
],
),
),
I ended up giving up on using Table and instead used Column and Row widgets. Here is my new code:
Column(
children: [
Expanded(
child: Row(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Expanded(child: TextButton(
child: Text('1'),
onPressed: () {},
)),
Expanded(child: TextButton(
child: Text('2'),
onPressed: () {},
)),
]),
),
]
);

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).

Icon rendered with offset

When I tried to use IconButtons, I noticed that they were rendered incorrectly - the icon itself was offset to the right bottom, while the clicking animation was perfectly fine. Now my question is: Is this issue related to my code or is it Flutter's fault?
This is the build method of the StatelessWidget the IconButtons are located in:
return Container(
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
IconButton(
onPressed: () => {},
icon: Icon(
Icons.play_circle_outline,
size: 50,
),
color: Color(0xff3C6E71),
),
],
),
);
This is how it looks when the button is clicked, the Icon itself is offset to the bottom right but the clicking animation is perfectly centered how it should be.
Probably some issue with the widget padding, you can try adding a padding with the value zero:
return Container(
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
IconButton(
onPressed: () => {},
padding: EdgeInsets.zero, // set padding to zero
icon: Icon(
Icons.play_circle_outline,
size: 50,
),
color: Color(0xff3C6E71),
),
],
),
);

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