Aspectratio of AspectRatio() widget is not respected

Viewed 577

Situation


    return Container(
      decoration: BoxDecoration(
        color: Colors.redAccent,
        borderRadius: BorderRadius.circular(13.0),
      ),
      child: Column(
        mainAxisAlignment: MainAxisAlignment.end,
        children: [
          Padding(
            padding: const EdgeInsets.all(8.0),
            child: Header(),
          ),
          Expanded(
            child: Pad()
          ),
        ],
      ),
    );

  • The children of the container are Header() (green widget) and Pad() (blue widget). Where Pad() has aspect ratio of 1 / 1 (square).

Header() widget:


    class Header extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return Container(
          decoration: BoxDecoration(
            color: Colors.green,
            borderRadius: BorderRadius.circular(13.0),
          ),
          child: Padding(
            padding: const EdgeInsets.all(8.0),
            child: Text("CONTAINER WIDGET WITH TEXT"),
          ),
        );
      }
    }

Pad() widget:


    class Pad extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return AspectRatio(
          aspectRatio: 1 / 1,
          child: Container(
            decoration: BoxDecoration(
              color: Colors.blue,
              borderRadius: BorderRadius.circular(13.0),
            ),
            child: Center(
              child: Text("WIDGET WITH 1/1 ASPECT RATIO")
            ),
          ),
        );
      }
    }

Problem summary

  • If the container with column is given more horizontal space then vertical, then the 1:1 aspect ratio of Pad() (blue widget) is respected and empty space is left out on both sides of the container (red widget). Here is a .gif for visual representation. So far no issue.
  • However, if the container recieves more vertical space then horizontal, then the 1:1 aspect ratio is is not respected and the square changes into rectangle Here is a visual representation

Expected / desired behaviour

  • When the container recieves more vertical space then horizontal, the widget with 1:1 aspect ratio should keep it's squared shape. To compensate for the additional space, it should either:

    a) Empty space should be kept above and below of the container (same as when more horizontal then vertical space is provided)

    b) The Header() widget should expand to compensate for the remaining space

What I tried so far

  • I suspect that the issue is a direct result of wrapping Pad() with the Expanded() widget. However, without the expanded widget the container with 1:1 aspect ratio would simply overflow, and not shrink.
  • If I also wrap the Pad() widget with Expanded(), then both of the widgets will take equal space (or provided ratio). However, I want the Header() to take as little space as necessary.
2 Answers

You could also position your Pad in the Center of the Expanded Widget:

Expanded(child: Center(child: Pad())),

With this solution, your whole UI will expand both horizontally and vertically to fill the whole screen while keeping the aspectRatio of 1.

enter image description here

Full source code:

import 'package:flutter/material.dart';

void main() {
  runApp(
    MaterialApp(
      debugShowCheckedModeBanner: false,
      title: 'Flutter Demo',
      home: HomePage(),
    ),
  );
}

class HomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Container(
        decoration: BoxDecoration(
          color: Colors.redAccent,
          borderRadius: BorderRadius.circular(13.0),
        ),
        child: Column(
          mainAxisAlignment: MainAxisAlignment.end,
          children: [
            Padding(
              padding: const EdgeInsets.all(8.0),
              child: Header(),
            ),
            Expanded(child: Center(child: Pad())),
          ],
        ),
      ),
    );
  }
}

class Header extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Container(
      decoration: BoxDecoration(
        color: Colors.green,
        borderRadius: BorderRadius.circular(13.0),
      ),
      child: Padding(
        padding: const EdgeInsets.all(8.0),
        child: Text("CONTAINER WIDGET WITH TEXT"),
      ),
    );
  }
}

class Pad extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return AspectRatio(
      aspectRatio: 1 / 1,
      child: Container(
        decoration: BoxDecoration(
          color: Colors.blue,
          borderRadius: BorderRadius.circular(13.0),
        ),
        child: Center(child: Text("WIDGET WITH 1/1 ASPECT RATIO")),
      ),
    );
  }
}

I solved my issue by putting another 1:1 AspectRatio() widget inside the original one.

class Pad extends StatelessWidget {

  @override
  Widget build(BuildContext context) {
    return AspectRatio(
      aspectRatio: 1 / 1,
      child: Container(
        decoration: BoxDecoration(
          color: Colors.blue,
          borderRadius: BorderRadius.circular(13.0),
        ),
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            AspectRatio(
              aspectRatio: 1 / 1,
              child: Container(
                decoration: BoxDecoration(
                  color: Colors.yellow,
                  borderRadius: BorderRadius.circular(13.0),
                ),
              ),
            ),
          ],
        ),
      ),
    );
  }
}
Related