In flutter, I want the Icon within a container to take up maximum size of the container - flutter

Widget build(BuildContext context) {
return Container(
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
Flexible(
flex: 1,
child: Container(
color: Colors.blueAccent
),
),
Flexible(
flex: 4,
child: Container(
color: Colors.deepOrangeAccent,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
//mainAxisSize: MainAxisSize.max,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
Icon(Icons.image),
],
),
),
),
Flexible(
flex: 2,
child: Container(color: Colors.blueGrey),
),
],
),
);
Screenshot
The Icon is taking its original size only. I want it to fill the container.
I have tried LayoutBuilder but the BoxConstraints have infinite height warning comes.
Please suggest any other options without using hardcoded sizes for any of the widgets.

Edit; So after reading your comment here is you should use a FittedBox instead (as suggested in the comments) and BoxFit.Fill property; so:
<Widget>[ Expanded(child:FittedBox(child: Icon(Icons.image),fit: BoxFit.fill)), ]
--
If you can change your icon to Image then you can use the BoxFit.fill property to stretch the image to fill the entire container (wrap the image in Expanded widget too).
Here is an example with a placeholder:
Flexible(
flex: 4,
child: Container(
color: Colors.deepOrangeAccent,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
//mainAxisSize: MainAxisSize.max,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
Expanded(child: Image.network('https://picsum.photos/250?image=9', fit:BoxFit.fill)
)
],
),
),

I would take the LayoutBuilder approach. You mentioned you had infinity warning, which might be because you don't dynamically pick between the height of your parent container or its width.
Depending on the orientation of your device, you might need to pick one or the other. The easiest way to cater for that is to pick the smaller of the two.
Widget build(BuildContext context) {
return Container(
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
Flexible(
flex: 1,
child: Container(color: Colors.blueAccent),
),
Flexible(
flex: 4,
child: Container(
color: Colors.deepOrangeAccent,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
//mainAxisSize: MainAxisSize.max,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
LayoutBuilder(builder: (context, constraints) {
var height = constraints.maxHeight;
var width = constraints.maxWidth;
return Icon(FontAwesomeIcons.addressBook, size: min(height, width));
}),
],
),
),
),
Flexible(
flex: 2,
child: Container(color: Colors.blueGrey),
),
],
),
);
}
}
Note: you'll need to import the 'dart:math' package to use the min() function.

Related

Align image and text in center in GridView in flutter

I am trying to align image and text in the center, it works when text is small but when i have large text then everything changes. I am using GridView which has 3 items on each row..
Widget buildItems(BuildContext context, String impagepath, String modulename) {
return Column(
mainAxisSize: MainAxisSize.max,
children: <Widget>[
Expanded(
child: CustomButtonWidget(
image: impagepath,
size: 100,
borderWidth: 5,
onTap: () {}
),
),
Row(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
Container(
width: double.infinity,
height: double.infinity,
child: Text("${selectlang.getAlbum(modulename, lang_selection)}"),
),
],
)
],
);
}
You need to use CrossAxisAlignment property of Column` widget
Use crossAxisAlignment: CrossAxisAlignment.center, in your Column widgets
Widget buildItems(BuildContext context, String impagepath, String modulename) {
return Column(
mainAxisSize: MainAxisSize.max,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Expanded(
child: CustomButtonWidget(
image: impagepath,
size: 100,
borderWidth: 5,
onTap: () {}
),
),
Row(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
Container(
width: double.infinity,
height: double.infinity,
child: Text("${selectlang.getAlbum(modulename, lang_selection)}"),
),
],
)
],
);
}
use crossAxisAlignment: CrossAxisAlignment.center inside column widget.

How to strech a column while centering their children

I want to expand a column horizontally while keeping the children (an icon and a text) in the center.
When I use CrossAxisAlignment.center it doesn't mathes its parents width. So I tried CrossAxisAlignment.stretch.
Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Icon(Icons.help),
Text('Please help!'),
],
),
Here the text was aligned left even though the icon is centerd.
I do not understand this and a solution would be highly appreciated.
have you tried wrapping column in a container and setting width to double.infinity?
Container(
width: double.infinity,
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Icon(Icons.help),
Text('Please help!'),
],
),
)
I found a hack might not the exact solution but works for me.
there might be other solutions
Added a SizedBox box widget with width because we need to center horizontally.
Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Icon(Icons.help),
Text('Please help!'),
SizedBox(
width: double.infinity, // it will take entire available device width
height: 0,
)
],
),
Another way.
Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Row(
children: <Widget>[
Expanded(
child: Container(),
),
Icon(
Icons.help,
color: Colors.white,
),
Expanded(
child: Container(),
),
],
),
Row(
children: <Widget>[
Expanded(
child: Container(),
),
Text('Please help!'),
Expanded(
child: Container(),
),
],
)
],
)
The right way to do is:
Center( // it helps column stretch
child: Column(
mainAxisAlignment: MainAxisAlignment.center, // it helps child stay in center
children: ...,
)
)

Flutter: How to align height of two adjacent widgets?

In bigger screens this isn't an issue and height of all widgets are the same but in smaller screens sometimes one of them is bigger than others because widgets extends themselves to contain content.
How can I fix it?
return ListView(
children: <Widget>[
Row(
children: <Widget>[
Flexible(child: _valueBox(), flex: 3, fit: FlexFit.tight),
Flexible(child: _dueDateBox(), flex: 3, fit: FlexFit.tight),
],
),
Row(
children: <Widget>[
Flexible(child: _advancePaymentBox(), flex: 3, fit: FlexFit.tight),
Flexible(child: _priceBox(), flex: 3, fit: FlexFit.tight),
],
),
],
);
It looks like it's because the text is overflowing to a new line. There is a widget called ConstrainedBox if you want to enforce a fixed size. You also might want to look at this package, it can dynamically resize your text to fit. https://github.com/leisim/auto_size_text
How about to use GridView?
I think it's more easier way.
This is just a sample code. I added 2 line text instead of image.
Widget _valueBox(){
return Container(color: Colors.blue,
child: Column(mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text("title"), Text("TestA", style: TextStyle(fontSize:50.0))]));
}
Widget _dueDateBox(){
return Container(color: Colors.yellow,
child: Column(mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text("title"), Text("This is long text", style: TextStyle(fontSize:50.0))]));
}
Widget _advancedPaymentBox(){
return Container(color: Colors.green,
child: Column(mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text("title"), Text("TestA", style: TextStyle(fontSize:50.0))]));
}
Widget _priceBox(){
return Container(color: Colors.pink,
child: Column(mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text("title"), Text("This is long text really", style: TextStyle(fontSize:50.0))]));
}
Widget getList(BuildContext context){
return GridView.count(
crossAxisCount: 2,
children: <Widget>[
_valueBox(),
_dueDateBox(),
_advancedPaymentBox(),
_priceBox()
],
);
}
And, It is the result.

Flutter put row into row

I need to create the following:
I could do it with code:
Row(
children: <Widget>[
Container(
width: 30
),
Column(
children: <Widget>[
Text("label"),
Container(
width: screenSize.width - 30, // <- this is problem
child: Row(
children: <Widget>[
Expanded( child: TextField() ),
Expanded( child: TextField() ),
],
),
),
],
),
],
);
Is it possible to do it in a different way, namely the line width: screenSize.width - 30?
You can use crossAxisAlignment inside Column widget and make it Stretch to get all remaining width in screen
Row(
children: <Widget>[
Container(
width: 30
),
Column(
crossAxisAlignment: CrossAxisAlignment.stretch, // <- Add this
children: <Widget>[
Text("label"),
Container(
child: Row(
children: <Widget>[
Expanded( child: TextField() ),
Expanded( child: TextField() ),
],
),
),
],
),],);
[Please read official flutter documentation of Column widget]
Column Widget
CrossAxisAlignment
Solution
Row(
children: <Widget>[
Container(
color: Colors.red,
width: 50,
),
Expanded(
child: Column(
children: <Widget>[
Text("label"),
Expanded(
child: Row(
children: <Widget>[
Expanded(
child: TextField()
),
Expanded(
child: TextField()
),
],
),
),
],
),
),
],
);
Explanation
It is about where you place Expanded instances.
You have a row, which can fill its parent if it included an Expanded child. So we defined the size of one of its children (Container), and the other is simply Expanded. The same goes for the Column child ..
Maybe starting with a simpler example makes it easier to understand. Please refer to this useful answer.
Output
P.S. Welcome to StackOverFlow, Dmitry!

Flutter: Trying to bottom-center an item in a Column, but it keeps left-aligning

I'm trying to bottom-center a widget at the bottom of a Column, but it keeps aligning to the left.
return new Column(
new Stack(
new Positioned(
bottom: 0.0,
new Center(
new Container(),
),
),
),
);
The existence of the Positioned forces the Container to the left, instead of centering. Removing the Positioned, however, puts the Container in the middle-center.
Align is the way to go if you have only one child.
If you have more, consider doing something like this:
return new Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[
// Your elements here
],
);
The easiest and the correct way to do it - use Spacer()
Example:
Column(
children: [
SomeWidgetOnTheTop(),
Spacer(),
SomeCenterredBottomWidget(),
],
);
Expanded(
child: Align(
alignment: FractionalOffset.bottomCenter,
child: Padding(
padding: EdgeInsets.only(bottom: 10.0),
child: //Your widget here,
),
),
),
I have used this approach,
What i want is, A layout always in bottom but whenever Keyboard pops-up that layout also comes over it
body: Container(
color: Colors.amber,
height: double.maxFinite,
child: new Stack(
//alignment:new Alignment(x, y)
children: <Widget>[
new Positioned(
child: myWidget(context, data.iconName, Colors.red),
),
new Positioned(
child: new Align(
alignment: FractionalOffset.bottomCenter,
child: myWidget(context, data.iconName, Colors.green)
),
)
],
),
),
1) You can use an Align widget, with FractionalOffset.bottomCenter.
2) You can also set left: 0.0 and right: 0.0 in the Positioned.
Just expanding the answers:
Spacer is an option no one mentioned yet; it is used in case you prefer not to use Positioned / Align.
Align works if you want to specify the alignment of a child inside a parent. Use it anywhere but directly inside Stack
Positioned is similar to Align, but works only under Stack directly.
Design everything using Expanded() is one of the easiest way to do this
Column(
children: [
Expanded(
child: Placeholder(),
flex: 1,
),
Expanded(
child: Placeholder(),
flex: 10,
),
Expanded(
flex: 2,
child: Placeholder(),
)
],
),
If you wish to leave content as it, can wrap it with scrollable.
Useful if you have inputs in the children:
return Stack(
children: <Widget>[
Positioned(
child: SingleChildScrollView(
child: Column(
children: children
..add(Container(
height: 56, // button heigh, so could scroll underlapping area
)))),
),
Positioned(
child: Align(
alignment: Alignment.bottomCenter,
child: button,
),
)
],
);
Widget _bottom() {
return Column(
mainAxisAlignment: MainAxisAlignment.start,
children: [
Expanded(
child: Container(
color: Colors.amberAccent,
width: double.infinity,
child: SingleChildScrollView(
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: new List<int>.generate(50, (index) => index + 1)
.map((item) {
return Text(
item.toString(),
style: TextStyle(fontSize: 20),
);
}).toList(),
),
),
),
),
Container(
color: Colors.blue,
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
'BoTToM',
textAlign: TextAlign.center,
style: TextStyle(fontSize: 33),
),
],
),
),
],
);
}
Wrap your Container in SingleChildScrollView() widget. Then it will not come above when keyboard pops up.
In addition of Stack:
to avoid floating container on keyboard, use this
return Scaffold(
appBar: getAppBar(title),
resizeToAvoidBottomInset: false,
body: