Home > Software design >  Flutter Align not working inside row contained in column
Flutter Align not working inside row contained in column

Time:06-23

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:

enter image description here

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:

enter image description here

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

enter image description here

  • Related