Interestingly, if I have to make a list of details with these widgets:
Row(
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: [
Text('some label'),
Text('some value'),
],
),
Row(
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: [
Text('some label'),
Text('some value'),
],
),
Every time I wrap them inside a Wrap
or Column
in a simpler manner.
I never achieved what I expected if I used Wrap
, like this:
Wrap(
direction: Axis.vertical,
spacing: 8.0,
children: [
Row(
mainAxisAlignment:
MainAxisAlignment
.spaceBetween,
children: [
Text('some label'),
Text('some value'),
],
),
Row(
mainAxisAlignment:
MainAxisAlignment
.spaceBetween,
children: [
Text('some label'),
Text('some value'),
],
),
],
),
The issue is that the contents are placed on the left side. Even I wrap the Wrap
widget with the SizedBox(width: double.infinity, child: ...)
I only achieved what I wanted (i.e., since I am using Row(mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [...],)
here) by this approach:
Column()
widget instead of Wrap()
widgetColumn(
spacing: 8.0,
children: [
Row(
mainAxisAlignment:
MainAxisAlignment
.spaceBetween,
children: [
Text('some label'),
Text('some value'),
],
),
Row(
mainAxisAlignment:
MainAxisAlignment
.spaceBetween,
children: [
Text('some label'),
Text('some value'),
],
),
],
),
Take note that the SizedBox(width: double.infinity, child: Column(...))
is redundant for this case, unless there's a use case that suggests it to do so.
Could someone explain it in more detail to understand why this is happening? Understanding this better could prevent implementing the wrong setup if we tend to use this kind of layout outcome.
P.S. The behavior remains the same if executed in DartPad
Here's the minimal, reproducible example:
import 'package:flutter/material.dart';
void main() => runApp(const MyApp());
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
debugShowCheckedModeBanner: false,
theme: ThemeData(colorSchemeSeed: Colors.blue),
home: const MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
final String title;
const MyHomePage({super.key, required this.title});
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text(widget.title)),
body: Padding(
padding: EdgeInsets.symmetric(horizontal: 16.0),
child: Column(
spacing: 8.0,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [Text('some label'), Text('some value')],
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [Text('some label'), Text('some value')],
),
],
),
),
);
}
}
It has to do with the purpose of the Wrap widget. The widget does not try to expand to the secondary axis, because that's where the subsequent runs will go.
Let's look at your example: you have set the Wrap axis to be vertical. That means it will start laying widget from top to bottom. However, when it reaches the end bottom of its constraints, it will "break a line" and move to the second run/column.
Hence, if it tried to expand the Row, it would consume all the space it would try to use on the following runs.