Flutter - Using AspectRatio Widget Examples

This tutorial is about how to set the aspect ratio of a widget in Flutter using AspectRatio widget.

Sometimes, you may care about the proportions of a widget more than its dimensions. For example, you want the width to be always twice as large as the height. For that purpose, Flutter has a widget called AspectRatio.

Using AspectRatio Widget

The constructor of AspectRatio is as follows

  const AspectRatio({
    Key key,
    @required this.aspectRatio,
    Widget child,
  })

It requires you to pass a named argument aspectRatio whose type is double. The passed value is the width : height ratio to be applied to the Widget passed as child. For better readability, you are recommended to pass the aspectRatio value as a fraction instead of a decimal. It doesn't impact the performance since Flutter computes it at compilation time.

To understand how it works, look at the below examples.

In the first example, there are size constraints that require the width and the height to be between 0 and 200. The aspect ratio is set to 2 : 1, which means the width should be twice as large as the height. The aspect ratio of the constraints is smaller than 2 : 1. If Flutter tries to use the width of the available space as reference, the height will be the half as large as the width. The resulting size can fit in the available space. If Flutter tries to use the height as the reference, the width will be twice as large as the height. Since, the resulting width violates the width constraint, it will be rejected and the first solution which use the width as the reference.

  Container(
    width: 200.0,
    height: 200.0,
    color: Colors.grey,
    alignment: Alignment.topCenter,
    child: AspectRatio(
      aspectRatio: 2 / 1,
      child: Container(
        color: Colors.teal,
      ),
    ),
  )

Output:

Flutter - AspectRatio - 200x200 - 2:1

In order for the child to have a different size from its parent, you must specify the alignment of the child. Otherwise, the size of the child will be ignored. You can set the alignment property if the parent has the property (for example if you use Container like the above example) or wrap the child inside an Align widget.

The second example uses the same size constraints which require the width and the height to be between 0 and 200. The width : height aspect ratio is set to 1 : 3, which means the height should be three times bigger than the width. The aspect ratio of the available space is greater than 1 : 3. If Flutter tries to use the width of the available space as reference, the height will be bigger than the allowed size. Therefore, Flutter will use the height as the reference instead and set the width to be one third of the height.

  Container(
    width: 200.0,
    height: 200.0,
    color: Colors.grey,
    alignment: Alignment.topCenter,
    child: AspectRatio(
      aspectRatio: 1 / 3,
      child: Container(
        color: Colors.teal,
      ),
    ),
  )

Output:

Flutter - AspectRatio - 200x200 - 1:3

In the next example, there are no constraints on both width and height. For this case, it will try to set the widget as large as possible based on the available space. The aspect ratio is set to 2 : 1, which means the width should be twice as large as the height. In this example, the aspect ratio of the available space is smaller than 2 : 1. Therefore, Flutter will use the height of the available space as the reference.

  AspectRatio(
    aspectRatio: 1 / 2,
    child: Container(
      width: 100,
      height: 100,
      color: Colors.teal,
    ),
  )

Output:

Flutter - AspectRatio - No Constraints - 1:2

AspectRatio may not work if you put it as the child of a tightly fitted widget such as Expanded

  Column(
    children: [
      Expanded(
        child: AspectRatio(
          aspectRatio: 2 / 1,
          child: Container(
            width: 100,
            height: 100,
            color: Colors.teal,
          ),
        ),
      )
    ],
  )

Output:

Flutter - AspectRatio - Expanded

As the solution, you can wrap the AspectRatio inside an Align widget. Expanded will force Align to fill the available area, but the child of the Align can have its own proportions.

  Column(
    children: [
      Expanded(
        child: Align(
          child: AspectRatio(
            aspectRatio: 2 / 1,
            child: Container(
              width: 100,
              height: 100,
              color: Colors.teal,
            ),
          ),
        ),
      )
    ],
  )

Output:

Flutter - AspectRatio - Expanded with Align

Based on the above examples, we can conclude that Flutter will try to use the biggest dimensions that's fit the size constraints.

  • If the aspect ratio to be set is smaller than the aspect ratio of the constraints, the height of the constraints will be used as the reference.
  • If the aspect ratio to be set is greater than the aspect ratio of the constraints, the width of the constraints will be used as the reference.
  • If the aspect ratio to be set is the same as the aspect ratio of the constraints, the dimensions of the child will be as large as the constraints.

AspectRatio Parameters

  • Key key: The widget's key.
  • double aspectRatio *: The aspect ratio to be set to the child.
  • Widget child: The widget whose aspect ratio to be set.

*: required

Full Code

Below is the full code of this tutorial.

  import 'package:flutter/material.dart';
  
  void main() => runApp(MyApp());
  
  class MyApp extends StatelessWidget {
  
    @override
    Widget build(BuildContext context) {
      return MaterialApp(
        title: 'Woolha.com Flutter Tutorial',
        home: _AspectRatioExample(),
      );
    }
  }
  
  class _AspectRatioExample extends StatelessWidget {
  
    @override
    Widget build(BuildContext context) {
      return Scaffold(
        appBar: AppBar(
          title: const Text('Woolha.com Flutter Tutorial'),
        ),
        body: Container(
          width: 200.0,
          height: 200.0,
          color: Colors.grey,
          alignment: Alignment.topCenter,
          child: AspectRatio(
            aspectRatio: 1 / 3,
            child: Container(
              color: Colors.teal,
            ),
          ),
        ),
  //      body: AspectRatio(
  //        aspectRatio: 1 / 2,
  //        child: Container(
  //          width: 100,
  //          height: 100,
  //          color: Colors.teal,
  //        ),
  //      ),
  //      body: Column(
  //        children: [
  //          Expanded(
  //            child: Align(
  //              child: AspectRatio(
  //                aspectRatio: 2 / 1,
  //                child: Container(
  //                  width: 100,
  //                  height: 100,
  //                  color: Colors.teal,
  //                ),
  //              ),
  //            ),
  //          )
  //        ],
  //      ),
      );
    }
  }

Summary

Setting the aspect ratio of a widget can be done using AspectRatio widget. While setting the aspect ratio, Flutter will try to set the widget as large as possible, as long as it doesn't violate the constraints. Make sure that if the parent has size constraints, you need to set the alignment of the child.

You can also read about:

  • Align: a widget used to align a child within its parent.
  • ConstrainedBox: a widget that imposes additional constraints on its child.
  • UnconstrainedBox: a widget that imposes no constraints on its child.