A Responsive Application
The first version of the Flutter Studio was built with a static canvas and one device (a Pixel) with fixed panels for code and property editors. The same property editors showed for different widgets, whether or not they applied to the current widget. The device shown was the same size regardless of how much space you had. It floated in a sea of white space on a large monitor and barely fit on a laptop screen. Whenever I coded on the go (on a 13” MacBook pro), I would find it hard to fit the source code, tool windows and model in one window.
I redesigned it to be responsive and work on more screen sizes:
As you can see above, the new version resizes the device and tool windows to fit the available space. The larger the screen, the bigger the displayed device will be. There is one properties editor that changes according to the selected widget. The generated source code and pubspec are on a separate tab. There are more features visible in the image, but I’ll get to those later. The point is, you can work on your design on any size screen, from an 11-inch laptop to a 30-inch monitor and have all of the tools and options visible.
More, Pixel-Perfect Designs and a New Tool
In the first version of the flutter builder, I used a static canvas based very loosely on my own test device, a Pixel phone. It was extremely inflexible and often inaccurate. It was not scaled accurately and it limited you to one device. I wanted to allow prototyping on any device, including ones you may not have. You may not have $1000 to get an iPhone X or be able to find a working 2012 Nexus 7, but your customers might use them.
For this new version, I’ve created a database of devices and statistics about them, using data mostly gathered from https://material.io/devices/ and various manufacturers’ websites and updated the application model painter to incorporate that information. Every device, from an Android One to the iPhone X are accurately shown, with the design scaled precisely for their screen. Selecting a new one is as easy as choosing from the dropdown.
As I’ve written before, I prefer to build tools. I wrote an application to manage devices and add new ones easily. In the spirit of sharing, I’ve made a version public. It runs on firebase. So you can view and download (as JSON) devices statistics at
You can also download the whole database or any device as a JSON file there.
But how can I use this information to help developers? Flutter uses one of the best aspects of Android: graphical objects are measured in a device independent unit based on real dimension (dp or dip, about 160 per inch). While a physical screen pixel on a Nexus 9 or iPhone X is much smaller than one on an original Nexus One, a 160x160dp button is the same size on both.
Given an accurate database of device metrics, including their screen sizes in dp, I could build a logical model of the application in dp and translate that to your screen’s graphical raster, for any device and display it scaled accurately to your screen.
By scaling the Flutter Studio model using real device statistics, I can give the user an accurate model of how the running application will look on a particular device, from an Android One reference phone (480×854 pixel screen; 320×569 dp screen; 4.5” diagonal):
To a Nexus 9 tablet (2048×1539 pixels; 768×1024 dp; 8.9” diagonal):
Notice how the same application elements take up less space on the nexus 9.
By using real models of the phones and allowing different aspects (landscape and portrait orientations), I can also allow developers to test different layouts quickly, before trying them on actual devices. While developing in Flutter is very, very fast with quick turnaround, this is a much faster way to prototype, especially if you need to test on multiple devices.
Sometimes scaling the application accurately for the device makes it hard to see the running application, especially on high density screen devices like the nexus 9. I can barely see my work while using a laptop, for example. With that in mind, I included a switch to turn off true device scaling.
Pictured above is a typical app on the nexus 9, with a standard Material RaisedButton, Image and FlutterLogo with scaling turned on (the switch is on the bottom left). It looks exactly like this running on the device. But it’s almost impossible to see the text on the button. You can switch off true scaling to see it, as shown below.
With scaling turned off less of the application is visible but you can see details on the app, even on a small screen. The application is not drawn to scale for that device, but it is visible.
Allowing you to quickly scale the app lets you work on the layout without reloading or changing the testing device. The less work you (the developer) have to do, the more you can focus on actual value. The tool should eliminate the busy work of testing on multiple devices.
I have tested the app using real devices (both IOS and android) and tools like rulers to ensure the real-world accuracy of the web-app on actual devices.
More Widgets, Better Editors
The first version of the app was based on an early alpha version of flutter and had a limited set of widgets. For this version, I at least wanted to match the list in the widget catalog (https://flutter.io/widgets/). While this is a moving target, I was able to include almost all of the widgets at the present time (May 2018, Beta 3). This includes some new ones like the FlutterLogo, RotatedBox and Opacity. It was personally helpful to include them since it forced me to use them and learn their quirks. As a bonus, components like FlutterLogo made me learn both the HTML canvas and Flutter transformation matrices.
Some of the widgets and decorations have very tricky API’s, and it’s not easy to figure out how to use them. I designed the properties editors for them to be (hopefully) intuitive. So you can play around with them and see how the code updates, making learning them much easier.
For example, gradients have an API that has some quirks. Allowing you to quickly play around with it using a graphical editor and examining the generated code makes learning the API much easier:
In addition to the widgets on the flutter.io site, I included some of the ones I have used frequently when coding actual Flutter apps, like FractionallySizedBox (which I often use to divide apps logically, independent of screen size) and DropdownButton. I also included others I used that are really not well documented. Two, in particular come up often: RadialGradient, and LinearGradient. They aren’t actual widgets, but they are really useful and their implementation has some quirks.
Hopefully giving others a tools to easily play around with them visually and produce working code will speed up the learning process. These widgets, once you understand them, are easy to use. But they are tricky to pick up and many of them are actually hard to discover.
In summary, the last version of Flutter Studio had 26 widgets. This version has about 50.
Icons are Easier
The old app had convoluted icon selector. Clicking on the icon button brought up a chooser, changing the icon. You then dragged it over to the app. This was a problem. The tool was inconsistent (it had a constantly changing icon). And it did not act like other parts of the app requiring two steps, one of which was not discoverable. It was the web equivalent of 3D Touch, long-press or right-click. The new version treats icons and icon buttons like any other widget. You drag it over then edit it using the properties panel.
The properties editor allows you to choose the color, size and glyph of the icon.
Themes are Widgets, too
Everything is a widget in Flutter, even themes. A Theme defines the typography and colors of an material app or the children of the Theme. This means you can divide your app into logical sections and theme each properly. The theme widget is found in the styling tab.
To style the entire application’s theme, click on the device frame (the grey part surrounding the actual application). The properties editor now shows the entire app’s theme.
The screenshot below shows me editing an application divided into two halves (using FractionallySizedBoxes). I dragged a Theme into each half. The top theme is a dark theme. The bottom is a light theme with a pink primary swatch. Any components in either half will share that theme’s colors and fonts.
Complete, Working Code and PubSpec
The last version of Flutter Studio only produced code snippets of the generated application. It also did not deal with assets (e.g., images) used. The new version produces fully working code and a working pubspec.yaml file with any images or fonts used. One of the biggest annoyances I had in learning how to use assets in Flutter was formatting the pubspec file properly and keeping track of images. I’m sure you’ve had this experience: you add an image asset to your app, uncomment the assets line in the generated pubspec file and the build fails. (The generated pubspec.yaml is formatted with spaces and the parser expects tabs.) One tab or space in the wrong place leads to errors. Also, you have to remember to remove images from the yaml file if you change or delete them.
The tool makes this a no-brainer. The entire yaml file is generated and any font or images used are added, properly formatted and with no duplicates. You can add themes, images and button styles to your heart’s content. The tool will filter out just the fonts and assets you use and add them to a complete, parseable yaml file for the project.
It will also produce a complete application, ready to run on any device, not just code snippets. The code the tool produces is complete and runs.
One Last Note
If you’re considering building a large web application, I really recommend considering Dart. FlutterStudio and the Device Database were both written using Dart. The very first version of the application was built in Google Web Toolkit because I knew it would work, having used it in anger. The last two versions were built using Dart. The new codebase, with all of the added features is significantly smaller than the original GWT version. This is not just because of the better compilers.
Dart encourages efficient code and has the structures and types to allow it (like futures and streams) at a foundational level. I hesitated to strongly recommend it in the past because it was not strongly typed, and I know from experiences that that can lead to problems in larger codebases. As of version 2, Dart is typed.