I need to have box alignment like on image below. I use Wrap Widget to wrap my items by two elements in a row. But as i see Wrap widget don't have stretch property for the crossAxisAlignment.
I use another method to build cardItem, to simplify my code, and re-use it for my four cards. Maybe you know some other Widgets to help to do it.
Can someone help me with it. Please see my code below:
class Transfers extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Transfers'),
),
body: Center(
child: Wrap(
spacing: 10,
runSpacing: 10,
children: <Widget>[
_buildTransferItem(
"assets/images/icon.png",
"Some Text of this box",
context,
),
_buildTransferItem(
"assets/images/icon.png",
"Text",
context,
),
_buildTransferItem(
"assets/images/icon.png",
"Some Text of this box",
context,
),
_buildTransferItem(
"assets/images/icon.png",
"Some Text of this box",
context,
),
],
),
),
);
}
Widget _buildTransferItem(
String transferIcon, String transferTitle, BuildContext context) {
return Container(
width: MediaQuery.of(context).size.width * 0.5 - 20,
height: ,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(12.0),
boxShadow: [
BoxShadow(
color: Color.fromRGBO(140, 140, 140, 0.5),
blurRadius: 6.0,
)
],
),
padding: EdgeInsets.symmetric(
vertical: screenAwareSize(20.0, context),
horizontal: screenAwareSize(20.0, context),
),
child: Column(
children: <Widget>[
Image.asset(
transferIcon,
width: screenAwareSize(72.0, context),
height: screenAwareSize(39.0, context),
),
SizedBox(height: screenAwareSize(7.0, context)),
Text(
transferTitle,
style: TextStyle(
fontSize: screenAwareSize(14, context),
fontWeight: FontWeight.w300,
),
textAlign: TextAlign.center,
)
],
),
);
}
}
How do I find the size of a widget in flutter? To get the size/position of a widget on screen, you can use GlobalKey to get its BuildContext to then find the RenderBox of that specific widget, which will contain its global position and rendered size.
A widget that displays its children in multiple horizontal or vertical runs. A Wrap lays out each child and attempts to place the child adjacent to the previous child in the main axis, given by direction, leaving spacing space in between.
A better approach is using Container widget. When you need to change width, height or add padding/margin to any widget you should wrap the target widget into a container. The container widget is for this kind of job.
What you need is InstrinsicHeight
widget.
Here is an example of how to solve your problem for any given number of cards in row. As you can see the _generateRows(List<String> labels, int numPerRow)
function gets a collection of card labels and a number of cards in a row as input parameters and generates the layout:
List<Widget> _generateRows(List<String> labels, int numPerRow) {
Widget _buildTransferItem(String transferTitle, int numPerRow) {
return Builder(
builder: (context) {
return Container(
width: MediaQuery.of(context).size.width / numPerRow - 20,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(12.0),
boxShadow: [
BoxShadow(
color: Color.fromRGBO(140, 140, 140, 0.5),
blurRadius: 6.0,
)
],
),
padding: EdgeInsets.symmetric(
vertical: 20,
horizontal: 20,
),
child: Column(
children: <Widget>[
Icon(
Icons.info,
size: 48,
),
SizedBox(height: 7),
Text(
transferTitle,
style: TextStyle(
fontSize: 14,
fontWeight: FontWeight.w300,
),
textAlign: TextAlign.center,
)
],
),
);
},
);
}
List<Widget> result = [];
while (labels.length > 0) {
List<String> tuple = labels.take(numPerRow).toList();
for(int i = 0; i< tuple.length; i++){
if (labels.length > 0) labels.removeAt(0);
}
Widget item = IntrinsicHeight(
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: tuple.map((s) => _buildTransferItem(s, numPerRow)).toList(),
),
);
result.add(item);
}
return result
.expand((item) => [
item,
SizedBox(
height: 20,
),
])
.toList();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Transfers'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: _generateRows(
["Some text of this box", "Text", "Some Text of this box", "Some Rather Long Text of this box", "Cool, yeah?", "Last"],
3,
),
),
),
);
}
The IntrinsicHeight widget takes into consideration intrinsic dimensions of the child which for most container widgets like Row, etc. will be definite numbers. But it comes with performance warranty of O(N^2) in complex cases as you may read in the API docs. Here are screenshots of cases when number of cards per row are 2 and 3. Please note that this parameter is passed just once and is not hardcoded anywhere.
If there's an odd number of items it will center last item:
The way you are applied width of Container using media Query. Same way you can apply for Height or you can write manual for example
height: 300.0,
And to match parent of Column you can write following code :
Column(
mainAxisSize: MainAxisSize.max, // match parent
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: <widget>[
// your widget
]
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With