Flutter is a popular open-source UI kit by Google, which allows building cross-platform applications with solid architecture. Speaking about mobile apps development, the technology allows code reuse across both Android and iOS operating systems. As a result, developers are able to produce high-quality apps that feel comfortable on different platforms and businesses can save budget and resources — both benefiting also from faster time to market of a new product.
Flutter bloc architecture is indeed sophisticated and provides many benefits. In this article, we will review the specific mobile app architecture and focus on its core principles and concepts. Also, we will speak about our unique cross-platform solutions for the global mobile app market we have implemented since 2019.
More about opportunities Flutter offers for web development read in our article to the topic.
Flutter-based neobank app concept by Surf. Learn more
The basics of Flutter architecture
There are two major parts – a framework with a UI library based on widgets and a software development kit (SDK).
- In a nutshell, a framework is a UI Library based on widgets, which contains various reusable UI elements, such as sliders, buttons, text inputs, and others. These elements can be later personalized based on your needs.
- An SDK is a set of tools to develop applications and compile your code into the native machine code for Android and iOS.
To work with the technology, you have to use the Dart programming language created by Google in October 2011. Since then, Dart has dramatically improved and remains one of the proper choices for developing mobile and web applications.
The engine is mostly written in C++ and remains at the core of Flutter. The engine is responsible for the low-level implementation of the core API, including accessibility support, Dart runtime, graphics text layout, and plugin architecture.
The applications are packaged similarly to other native applications in relation to the underlying operating system. A platform-specific embedder coordinates with the underlying operating system for access to input and rendering surfaces. Besides, the code can be integrated into an existing application as a module through the use of the embedder.
Flutter architecture diagram
Flutter is arranged as a layered, extensible system. It functions as a sequence of independent libraries, with each of them depending on the underlying layer. Each part of the framework level is replaceable, and no layer has privileged access to the lower layer.
As a rule, developers work with the framework written in the Dart language. It incorporates the layout, a rich set of platforms, as well as foundational libraries comprising multiple layers. If we look from the bottom to the top, these layers are arranged as follows:
- Basic building block services and foundational classes, such as animation, gestures, and painting, offer commonly used abstractions over the underlying foundation.
- The rendering layer brings forth an abstraction for working with layout and building a tree of renderable objects.
- The widgets layer introduces the reactive programming model. Each class in the widgets layer corresponds with a render object in the rendering layer. Besides, the widgets layer can be used to define combinations of reusable classes.
- The Cupertino and Material libraries provide all-inclusive sets of controls that implement the iOS or Material Design languages through the use of the widget layer composition.
Flutter architecture components or Everything is a widget
On every side, widgets are the core Flutter architecture components and the major building blocks of the app’s user interface. Widgets make use of gesture recognition and advanced animation. Subsequently, they render the results to the Skia canvas, a graphics engine written in C/C++ that commands the CPU or GPU to complete the drawing on the device.
Here is a typical bloc architecture example, a bare minimum stateful widget.
class MyApp extends StatefulWidget {
@override
State<StatefulWidget> createState() {
return MyAppState()
}
}
class MyAppState extends State<MyApp> {
@override
Widget build (BuildContext context) {
return OneOrMoreWidgets;
}
}
Widget composition
Widgets are composed of many single-purpose widget blocs that produce powerful effects when combined. Flutter uses the same basic concept (a Widget) in the widgets layer in order to represent animations, drawing to the screen, layout, navigation, state management, theming, and user interactivity.
As for the animation layer and the rendering layer, there are hundreds of widgets as well. Besides, there are utility widgets that benefit from the compositional approach.
Widget hierarchy
Widgets form a composition-based hierarchy. Each widget is located inside its parent and receives context from there. This hierarchy is present all the way up to the root widget. In addition, the widget hierarchy is broad by design to increase the feasible number of combinations.
When responding to various events, apps update their user interface by commanding the framework to replace a widget in the hierarchy. The framework efficiently updates the user interface after comparing the new and old widgets.
Widget classes and categories
The framework establishes two paramount classes of widgets: stateful and stateless. If the unique characteristics of a widget have to change depending on different factors, it is classified as stateful. If a widget has no mutable state and its properties remain unchanged over time, it is called stateless.
Based on their features, widgets in Flutter can also be grouped into multiple categories:
- Layout widgets
A large number of widgets with a layout feature to allow composing multiple widgets into a single widget. The most popular layout widgets include Center, Column, Container, Row, and Stack.
- Platform-independent / basic widgets
A substantial number of basic widgets to create both complex and simple user interfaces in a platform-independent manner. They include text, image, and icon.
- Platform-specific widgets
They include Android-specific widgets and iOS-specific widgets. Android-specific widgets are called Material widgets. They are configured based on Material Design guidelines by Android OS. iOS-specific widgets are called Cupertino widgets. They are designed in accordance with Human Interface Guidelines by Apple.
- State maintenance widgets
All widgets belong either to stateful or stateless widget categories.
Flutter’s rendering model
At some point, you might wonder: how can a cross-platform framework offer comparable performance to single-platform frameworks?
Then we should think about the ways how traditional Android apps perform. Obviously, one first uses the Java code of the Android framework when drawing. The Android system libraries supply the components responsible for drawing to a Canvas object, which Android can then render with the Skia canvas.
Cross-platform frameworks usually attempt to smooth out the inconsistencies of each platform representation by creating an abstraction layer over the underlying native iOS and Android UI libraries.
App code is frequently written in an interpreted language like JavaScript, which must, in turn, interact with the Objective-C-based iOS system or the Java-based Android libraries to display UI. Consequently, it adds significant overhead, particularly where there is a lot of interaction between the app logic and the UI.
On the contrary, Flutter bypasses the system’s UI widget libraries in favor of its own widget set and thus minimizes the abstractions. Its visuals are painted by the Dart code. It gets compiled into the native code, which utilizes Skia for rendering. As part of the engine, it also embeds its own copy of Skia.
Even if the phone has not been updated with a new Android version, it allows the developer to upgrade the app and to stay updated with the latest performance improvements. The same applies to Flutter on other native platforms, such as Windows, iOS, or macOS.
How does Flutter integrate with other codes?
A range of interoperability mechanisms are available, whether you embed native controls in a Flutter app or embed Flutter in an existing application.
You can add custom code for mobile and desktop apps through a platform channel. It is a simple mechanism for communicating between the platform-specific code of your host app and your Dart code.
You can send and receive messages between a platform component written in a language like Swift or Kotlin and Dart by creating a common channel. Data is serialized from a Dart type into a standard format and then deserialized into an equivalent representation in Kotlin or Swift.
What are the benefits of Flutter application architecture?
- The modern and simple framework
The SDK allows you to create a real native-looking application without a bunch of code.
- Quick compilation procedure
It is possible to change your code and observe the changes in real-time in case these are not significant modifications.
- Proper choice for MVPs
The MVP architecture is fully performant and not different from a native app. If you need to create a mobile application for investors as soon as possible, then Flutter is an excellent choice. It is much cheaper since you don’t need to create two mobile apps for iOS and Android simultaneously.
- Great MVVP architecture
The MVVP architecture also has a string of advantages. First, it offers alternatives to Android architecture patterns. Second, it provides a transparent interface to view the controller. Third, it makes testing more accessible by breaking the alliance between app logic and UI.
- Flutter architecture Github
At present, the technology has a number of repositories on Github. Thousands of developers globally have embraced Flutter’s complete package and left good reviews.
Our Flutter architecture best practices
Surf’s Flutter department has existed for several years thus far, and we have successfully completed numerous corporate projects, ranging from small apps to full-fledged e-commerce and banking applications for some large companies.
At the beginning of our journey, we were hesitant about which basic architecture concept to choose among BLoC, Redux, Vanilla, and MobX. Eventually, we have decided to move away from these concepts and focus on our specific corporate tasks. We have set up the goal to create an architecture that would allow our Android and Flutter developers to quickly switch tasks between technologies.
This is how our team adapted the MWWM (Model-View-View-Model) pattern for Flutter architecture. Subsequently, we replaced “View” with “Widget” to make it simpler for devs.
The major advantage of such an architectural approach is that it allows splitting the layout and the logic, both business logic and the presentation layer logic. At the same time, it is worth noting that we also use regular Flutter widgets as they remain indispensable.
Surf projects
Approximately 70% of the company’s customers make their purchases via mobile devices, and the average app purchase is usually higher than the average offline purchase. The use of Flutter has saved the business 40% of the budget compared to native development.
In partnership with a large bank, we have created the world’s second banking app using Flutter.
In 2020, YouTube still failed to provide a vertical video view option. Nevertheless, our Client wanted to possess a quality streaming platform to enable users to watch its content on mobile phones. In less than a month, we have produced the desired Flutter solution.
Until recently, the company’s general managers, shift supervisors, and area coaches had to conduct numerous pieces of paperwork on hard copy. To enable KFC staff to create digital reports instead, we have developed a cross-platform corporate app for smartphones based on Flutter.
Bottom line
Let’s recap what we’ve learned in the above article.
- Flutter application architecture is arranged as an extensible, layered system and functions as a sequence of independent libraries.
- Widgets are the major building blocks of the described architecture. Complex widgets are composed of already existing widgets.
- Being a cross-platform framework, Flutter offers comparable performance to single-platform ones.
- It is possible to embed Flutter in an existing application or embed native controls in a Flutter app.
- The benefits of Flutter architecture include a simple framework, quick compilation, and active Github community. Besides, such architecture is a great choice to quickly create MVPs.