Meet Shuttle—Polidea's tool that makes easy, secure and fast mobile apps distribution possible.
Native Developer’s Look on Flutter
Flutter is a hot topic among the developers. In case you haven't heard about it—it's a new mobile app SDK that helps developers and designers build modern mobile apps for iOS and Android (at least according to the official website). The first commit was made on 23 Oct 2014. To be honest, I've never been a fan of cross-platform mobile development. Every time I’ve used one of the apps built this way I’ve had this weird feeling that something is wrong. I mean things like scrolling speed, button behavior, performance, and responsiveness. When I first heard about Flutter I was skeptical. I thought that it's no different than other similar frameworks so it's not worth my time. I have to admit that I was wrong and despite some minor flaws, it's just awesome.
What's so special about it?
Flutter is an open source project developed mainly by a group of engineers at Google. But it also has external contributors (there were about 130 of them at the time of writing this post). It's written in Dart language which is also maintained by Google. Of course, I would prefer Kotlin but when Flutter's development started, Kotlin was not so popular as it is today so Dart seems like a reasonable choice. Having Flutter and Dart in control allowed for creating an awesome tooling and IDE integration. It works seamlessly with IntelliJ and Android Studio. Just think about things like debugging and Hot Reload that actually work. But the most important thing that makes Flutter special for me is the fact that the created apps are really smooth and beautiful. Flutter has a built-in library of Material (Android) and Cupertino (iOS) widgets that are pixel-perfect implementations of Google's and Apple's guidelines. As an Android developer, I have to admit that it has more material widgets implemented than are available even on Android. Playing with demo app convinced me that cross-platform apps can look and feel good. Flutter takes care of things like scrolling speed, so it feels as close to native Android/iOS app as possible. It's impressive how much attention to details the developers had paid. At that point I knew that I wanted to give it a try and experiment with it for about 2 weeks.
I love creating fancy, custom UI so I decided to test Flutter capabilities in this area. Recently I was working on Folx app, which has a lot of non-standard widgets and patterns. (You can read more about this project here. As it turned out I had to change my plan twice. You'll find out why in a minute.
My first idea was to implement a screen with a map to test how the communication between Flutter and OS works. It turns out that Flutter doesn't support OpenGL yet, so there is no
VideoView. I know that the team is working hard on it so it will be available eventually. But I had to change my project idea at this point.
Folx app has an interactive main screen with rounded buttons that are morphing into rounded rects and translating around the circle. The content of the circle uses crossfade effect to change its values and all of that is controlled by a user swipe gesture. At the beginning, I was convinced that it’s extremely complex but after reading the Flutter docs I’ve decided to give it a try. It quickly turned out that making Flutter's
PageView widget to use crossfade instead of translating to animate changes between pages is not trivial. It's definitely doable but it required reaching the lower level machinery. Taking into account that it’s just a small part of the whole screen, I felt that it would be a waste of time. I had to change my project idea again.
I didn't want to waste more time on thinking what to code so I decided to implement two or three first screens of the Folx app. In the meantime, I found out that Flutter can be used as a
View on Android and
UIView on iOS. Since the app idea doesn't seem spectacular I thought that maybe I could at least make the background animated like in the original app where it uses OpenGL to render it.
Maybe Flutter view could be made translucent and then background (or even maps) could be rendered natively? I gave it a try and it almost worked. “Almost” because there is a bug. I can't use it so the background will be a static image.
From that time, I’ve focused on implementing the screens as close to the original as possible. The first thing I did was to implement styled buttons, add custom fonts, define colors etc. In Flutter all of these things you do in Dart code. There is no resource system similar to Android. I have to say that it was the thing I missed the most. Anyway, creating custom widgets is simple and fun! You basically compose them out of other widgets like
Container (for background). I remember learning about custom views on Android, where the learning curve is much steeper. Here I was able to create all necessary widgets in a couple of hours. Making
TextField look like in Folx was quite time-consuming. Flutter does a great job in implementing Material Spec but Folx uses slightly different styles and behaviors. I was worried that it won't be possible since copying and modifying original views on Android is often painful (they use internal APIs that are not available outside the framework). I was pleasantly surprised to discover that I was able to just grab the
TextField implementation from Flutter and modify it the way I needed. The code is pretty straightforward and easy to change. Having widgets ready, I could finally start implementing screens. As I already got used to the style that Flutter enforces devs to use, it was a matter of hours to make them look great. Of course, it was not a seamless process. It turned out that Flutter doesn't allow to put flexbox widgets inside scrollable containers yet so I had to assume that the screens won't be scrollable. The other thing that slowed me down was animations. Animations in Flutter are widgets too and you compose them like the rest of the components. This requires a change of your mindset. But even when I finally understood how to use them, I was not able to implement an animation for the widget size changes. Like I said before—it's definitely doable but it requires using lower level mechanisms so I decided to leave it without animation.
Check out a couple of screenshots from the final app I was able to make:
I won't lie, Flutter is not perfect yet. It lacks some important things like OpenGL,
VideoView or the accessibility support. But it’s just a matter of time—all of these things are going to be developed one day. After all, it's an active project, as you can see on the public roadmap. Many of you are probably wondering—what about tests? Shouldn’t we care about testing? I have great news for you: Flutter supports testing and it's awesome! You can even write unit tests for UI! Unfortunately, I didn't have enough time to try it but you can read more about those tests here.
Flutter changed my point of view on cross-platform frameworks. Its performance, focus on details and UI, Dart as a language, IDE support, and community around it gave me hope. I think that someday we'll be able to write an app without sacrificing user's habits and it will work great on both Android and iOS (and Fuchsia—I didn't mention that Flutter is also a framework to write Fuchsia apps). Wonder no more and just go and try it yourself! And if you have any question you can ask the Flutter team on GitHub, Gitter or subscribe to their mailing list.
Visit our GitHub to check it out yourself!
How can we help?
Is going native the only way to succeed? We have touched upon this issue in our article devoted to React Native—you can check it here. We would be more than happy to help you decide, just tell us about your project!.
- MichałSenior Software Engineer