I have a row with 3 items: an IconButton
, a Text
, and a SizedBo
x 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