Learn To Make Responsive Design In Flutter

A lot of Flutter developers, both beginners and intermediates often struggle with responsive design in Flutter.

In this post, we will learn how to make responsive widgets in Flutter which are supported in different devices.

Introduction

For the purpose of learning responsive design, we will refer to the following UI design.

Basically, this is a Category screen with a list of categories placed in two columns.

Each Category card has a fixed width and height. Then there is space between the cards and horizontal padding as well.

Mistake That Lead To Unresponsive Widget Designs

The main reason which lead to unresponsive widget designs is making use of fixed heights and widths in Flutter widgets.

For example, in the design specs created by the designer in Figma, we see the following dimensions:

Please don’t mind my rough drawing by hand here since no scales were used 😛

Category Card specs:

  • Height = 260
  • Width = 170
  • Horizontal Padding = 18
  • Gap Between = 24

If we look at the total width occupied, it is going to be 400 units.

(2 x card width) + (2 X padding) + Gap Between = 400

Now if we use these exact widths while designing our Flutter widgets, then things are definitely going to break on small devices whose dimensions are smaller than 400.

This is wrong which leads to unresponsive widgets in Flutter.

Row(
  children: [
    Container(
      height: 260,
      width: 170,
      color: Colors.grey,
      padding: EdgeInsets.only(left: 18),
      child: Column(
        children: [
          //card content for text and image
        ],
      ),
    ),
    SizedBox(width: 24,),
    Container(
      height: 260,
      width: 170,
      color: Colors.grey,
      padding: EdgeInsets.only(right: 18),
      child: Column(
        children: [
          //card content for text and image
        ],
      ),
    )
  ],
);
Unresponsive design overflow error in Flutter in Google Pixel 3A

Solution To Build Responsive Widgets In Flutter

Clearly, we have now seen that using fixed widths and heights lead to pixel overflowing errors.

So, how do we get responsive design in Flutter widgets?

As mentioned before, the first thing to do is avoid using fixed widths and heights when designing widgets and start using ratios.

In theory, we can assume the following ratio:

Height in Design / Width in Design = Height in Device / Width in Design

We already know the height and width of design spec. Now the question is how do we calculate the responsive height and width of device?

MediaQuery To The Rescue

In order to get the height and width of device where our Flutter app is running, we can make use of MediaQuery which gives us access to the device’s size information.

Calculating Responsive Width In Flutter

final MediaQueryData mediaQueryData = MediaQuery.of(context);

final double deviceHeight = mediaQueryData.size.height;

final double deviceWidth = mediaQueryData.size.width;

Once we know the device’s width, we can calculate the card’s responsive width as follow:

final double responsiveWidth =
     (deviceWidth / 2) - padding - (spaceBetween / 2);

Basically, we are dividing the total available space into two parts and subtracting the padding space to calculate the width here.

Download Free Books To Learn Flutter

Calculating Responsive Height In Flutter

Next, we can also get the responsive height now using the responsive width value from our previous equation:

final double responsiveHeight =
    (heightInDesign / widthInDesign) * responsiveWidth;

Final Responsive Design In Flutter Code

We have now learnt how to calculate the responsive width and height of any widget. The final code base implementation for our current use case is here.

final MediaQueryData mediaQueryData = MediaQuery.of(context);
final double deviceWidth = mediaQueryData.size.width;

final double heightInDesign = 260;
final double widthInDesign = 170;
final double padding = 18;
final double spaceBetween = 24;

final double responsiveWidth =
    (deviceWidth / 2) - padding - (spaceBetween / 2);

final double responsiveHeight =
    (heightInDesign / widthInDesign) * responsiveWidth;

return SingleChildScrollView(
  child: Padding(
    padding: EdgeInsets.symmetric(
      horizontal: padding,
    ),
    child: Row(
      children: [
        Container(
          height: responsiveHeight,
          width: responsiveWidth,
          color: Colors.grey,
          child: Column(
            children: [
              //card content for text and image
            ],
          ),
        ),
        SizedBox(
          width: spaceBetween,
        ),
        Container(
          height: responsiveHeight,
          width: responsiveWidth,
          color: Colors.grey,
          child: Column(
            children: [
              //card content for text and image
            ],
          ),
        )
      ],
    ),
  ),
);

Responsive design in Flutter

Using this technique, we can make any widget responsive in Flutter.

Best wishes~