At Newsvoice we have always been mobile first, over 95% of our app users are on mobile phones. We have really high ratings on App Store and Google Play, but they have occasionally been dragged down by tablet users complaining about the poor experience on tablets and the lack of a landscape mode. It was definitely time for a tablet version. We had a large iPad Pro to test on, but how about all other possible screen sizes?
If you enjoy this article and find it useful, please consider supporting me by downloading the free Newsvoice app and giving us a five star review. It means a lot, and you will get a great news app too. Thanks!
Running iOS Simulator with multiple windows
One way to test simultaneously on multiple devices is to use iOS Simulator and open multiple windows with different virtual devices. You can run your code on all devices at the same time with the “flutter run -d all” command, it even allows you to hot reload all instances at once. This works reasonably well, but it will eat up almost all of your computer’s processing power and you will have to switch between lots of windows. Also, it currently only works on the command line, and what about Android?
I started thinking about ways to more quickly test on different form factors, or even better, how to emulate the devices and resolutions on my large iPad Pro. After some experimentation with the MediaQuery class, I came up with the DeviceSimulator widget. You can find it on Pub.dev.
By inserting DeviceSimulator at the root of your widget tree, you allow it to override the properties of MediaQuery and Theme. DeviceSimulator will emulate different resolutions and devices, it will even render a mocked up system status bar. You can quickly slide between the screen sizes and your app will update immediately.
For obvious reasons, device simulator will only work on larger devices. However, it works well in iOS Simulator if you don’t have a tablet for testing. An added benefit is that DeviceSimulator makes it really easy to take screenshots of different devices for App Store and Google Play. This is especially convenient as App Store requires you to include screens from a minimum of four different devices.
MediaQuery is your best friend
With great testing for all possible screen sizes in place, how do you actually make your app render beautifully under all circumstances? This is where MediaQuery comes into play. MediaQuery allows you to check the specifics of the device you are running on, including reading the screen orientation and size, and which platform you are running on.
Depending on the screen size you can choose to build a different set of widgets. For instance, on a larger screen you may want to use a drawer that is always visible, while you may want to show it modally on a smaller phone screen.
You can accomplish this by getting the MediaQuery of the current context and building a different set of widgets depending on the screen size.
Adapting to the size of the parent container
Many times it makes more sense for a widget to adapt its appearance to the size of its parent container. This is especially true for widgets that are not top level. For instance, it can be useful for smaller components or a widget that can appear both in full screen and be embedded in other containers. The easiest way to achieve this in Flutter is through a LayoutBuilder.
The example above will return different widgets depending on the size of its parent container.
Different looks for each platform
Different platforms have a different look and feel. Android devices have different looking switch buttons than iOS, the icons are different, and scrolling mechanics are different. If you want your app to feel more native, this is something that you need to adapt to.
Luckily, Flutter provides components that feel native to each platform. Material design is native to Android, but you can also access the iOS style components through the Cupertino library. Some widgets have the .adaptive constructor, use it to create widgets that feel native to the platform you are running on.
You can also use the current Theme to figure out which type of platform you should build for. An equivalent to the example above would be to write the code like below. (This is obviously not recommended for the widgets that have the .adaptive constructor, but the pattern is useful for more complex situations.)
Hopefully, you now have the basic tools to start creating great looking apps that scale across any device. Feel free to drop me a line if you found this useful, or if you have any suggestions for improvements.