Build Responsive UIs in Flutter

Raouf Rahiche
Flutter Community
Published in
7 min readOct 16, 2018

Designers love making responsive UIs but implementing them in real life is not that easy. As a Flutter developer you should’t say NO to your designers. so let’s make them happy again.

TDLR :

  • In responsive UI we don’t use hard-coded values for dimension and positions.
  • Use MediaQuery to get the real-time size of the window.
  • Use Flexible and Expanded widgets to get a flexible UI that works with percentage rather than hardcoded values.
  • Use LayoutBuilder to get the ConstraintBox of the parent widget.
  • You can get the orientation of the device using MediaQuery or OrientationBuilder.

What are the components of responsive design?

In responsive design apps, we have three major things to consider: size, orientation, and device type and whenever any of them changes, the app UI changes.

For example if you have a list of images in one column in portrait mode it should become two columns in landscape mode to show as much as possible to the user in one page and in this little example the UI depends on the orientation of the device in the next part we will discuss each component with examples.

What’s the problem?

The main issue here is the hard-coded values for dimension and positions of your UI widgets. So to solve the problem just don’t use them, right? Yes but that’s just to solve one part of the problem because in responsive UI you don’t just scale Widgets, sometimes you re-position them and other times you change them according to the available space. In this article, I will give you some tips on how to do that.

INFO: The unit of measurement in flutter is logical pixels.

1. Different screen sizes

Flutter support both android and IOS devices and both of them come in a wide variety of sizes it’s impossible to make a layout for each one of them but it’s possible and very easy to make your one layout scale to fit all of them and in Flutter we have a set of Widgets that help in this situation. let’s talk about some of them :

The MediaQuery is an InhertedWidget that gives you information about the current media(AKA the windows that content your application) such as the size, orientation and Pixel Ration of the device.

So for example if you have a drawer menu and you want to show it only if the media width is less then 600 and if it’s greater then that you will show a normal menu in the left.

NOTE : 600 is just an example for an android tablet screen but if you want to know more about the right numbers you should read this for android and this for IOS

This example is very simple we have a Scaffold that contains a Row with two children a Text in the center and a menu in the left that will be shown only if the condition is true. the interesting the third line where I declared media

Now if you run this app in tablet and medium android device you will get different UIs :

TIP: Use the breakpoin package to get useful information about the screen and break your screen layout into columns that you can easily hide/show depending on the window size

As of now Android and IOS has real-time window change, for example, we have Multi-Window Support and in this mode, the size of the app can be modified by the user and using MediaQuery you can still get the exact size, let’s run the previous app in Multi-Window mode and as you can see it works as expected.

In the previous example, we didn’t just use the MediaQuery to get this flexible design we used other widgets like Flexible which follow the FlexBox layout system let talk about this a little bit more.

Flexible and Expanded are two widgets that you can use inside a Row, Column, or Flex to give their children the flexibility to expand to fill the available space and the main difference between them can be shown in this example :

buildFlexible and buildExpanded are just two functions they return the right widget.

For example :

NOTE: If you don’t provide a flex value the default value is 1

So the difference is that the Expanded widget requires the child to fill the available space while Flexible does not. and now you can use them to distribute space between multiple items

The MediaQuery widget will give you the global size available for your application meanwhile you can think of LayoutBuilder as a local MediaQuerybut more focus on the size constraints so it will provide you with the parent widget’s constraints to read them and decide what to display according to them

NOTE: in flutter everything is a widget even the app so you can achieve the same thing we did in the first example by using the LayoutBuilder just by wrapping your Scaffold inside a LayoutBuilder and use the maxWidth value in the condition.

This widget is a must if you want your fixed-size widgets to scale and position them self to fit the available space. Take a look at this example where I have three Text widget’s, With the help of FittedBox they will scale them self to fit the screen width always in both orientations.

PRO TIP: use the flutter_device_preview package to test your app in deferent real screen size as well as with deferent orientations.

2. The Orientation

The orientation change is another type if run time size change just like what we saw in the multi-window example above but in this time it’s more specific for phone users because most of the time people change from portrait to landscape mode to get more data in the viewport.

  • access the device orientation

using MediaQuery:

using OrientationBuilder :

NOTE: both of the ways use the same logic which is if the width > height then it’s portrait otherwise it’s landscape but the OrientationBuilder uses the parent BoxConstraints so unless you provide an explicit maxWidth that’s greater then the maxHeight you will get the right orientation .

Now let me show you a simple example where this comes handy. let’s say you have a login page that looks like this :

Now if you change it to landscape it will look like this :

This is not something you should show to the user, in the login page the user expects to see the input field to write the login information. Let’s fix this using the OrientationBuilder.

The fix is simple if the orientation is portrait then the size is 200.0 otherwise it’s 100.0 so now it will look a little bit better.

Okay that’s it for orientation but if you want to see how to deal with orientation in a crazy way take a look at this implementation by Simon Lightfoot :

Should I care about Desktop support?

As some of you know google is working on a new OS called fuchsia which will be available for desktop and mobile as well and flutter is going to be the official development tool for it.

As of 2019 Desktop is now a primary goal for the flutter team

So the apps you create now for android IOS will work on fuchsia as well. The question here is: should I care about desktop support(in term of responsive UI)? My answer is No for the moment because in fuchsia the app can work in two modes the desktop and mobile mode and even if you run your app in desktop mode it will look good if you follow the above advice.

Conclusion

That’s it for me I hope you enjoyed this article if you did feel free to clap and share with others if you didn't please let me know in the comment’s what I am missing. And for the final advice I would say :

in responsive design don’t think about specific device because you will just get in trouble

all the examples shown in this article can be found on this repo

Follow me and the flutter community on twitter for more articles.

--

--