I have a row with 3 items: an IconButton, a Text, and a SizedBox with a width set. The row is inside a Column with anther child which is Expanded.
I'm trying to get the IconButton to align to the TOP of the row. I thought that wrapping this inside an Align with alignment topCenter would work, but it doesnt:
I can't figure out why. Here's the code:
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: SafeArea(
child: Column(
children: [
Row(
children: [
Align(
alignment: Alignment.topCenter,
child: IconButton(onPressed: () {}, icon: Icon(Icons.arrow_back)),
),
const Expanded(child: Text("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat")),
SizedBox(
width: 80,
child: AspectRatio(
aspectRatio: 0.7,
child: Placeholder(),
),
)
],
),
const Expanded(
child: Placeholder(),
)
],
),
),
),
);
}
}
Interestingly, if I remove the outer Column, the Align works:
I'd like to understand why, and how to resolve this layout issue. Note that I don't want to set the Row crossAxisAlignment to start, because this would then misalign the SizedBox containing the Placeholder to the top instead of the center of the row.
CodePudding user response:
You can wrap the Row in an IntrinsicHeight to fix it, so like this:
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: SafeArea(
child: Column(
children: [
IntrinsicHeight(
child: Row(
children: [
Align(
alignment: Alignment.topCenter,
child: IconButton(onPressed: () {}, icon: Icon(Icons.arrow_back)),
),
const Expanded(child: Text("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat")),
SizedBox(
width: 80,
child: AspectRatio(
aspectRatio: 0.7,
child: Placeholder(),
),
)
],
),
),
const Expanded(
child: Placeholder(),
)
],
),
),
),
);
}
}
It's because the Row doesn't know what height it is before all children are rendered. So the Align doesn't know what it's height should be. Without the Column it does know because then the Row knows it will have all available space
CodePudding user response:
Align is not working cause the row is not given a height so it doesn't know on which basis it will align its child
you can solve this by either giving the row a fixed height (which is not preferable if the text can grow)
or you can solve it by wrapping the Row in an Expanded widget and control its size with respect to the other Expanded widget through flex attribute
like this
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: SafeArea(
child: Column(
children: [
Expanded(
flex: 1,
child: Row(
children: [
Align(
alignment: Alignment.topCenter,
child: IconButton(onPressed: () {}, icon: Icon(Icons.arrow_back)),
),
const Expanded(child: Text("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat")),
SizedBox(
width: 80,
child: AspectRatio(
aspectRatio: 0.7,
child: Placeholder(),
),
)
],
),
),
const Expanded(
flex: 5,
child: Placeholder(),
)
],
),
),
),
);
}
and the output is this



