Toggle navigation menu. MENU

Why is Flutter worth learning about and using?  We have already seen some details about what it is and how it works, and I have brought up some great aspects of Flutter, but I would be remiss if I did not bring up some vibrant app examples for you to see in action.  Luckily for us, a development team named gskinner has built, for public review, a set of open-source examples made specifically to showcase some of Flutter’s incredible UI capabilities.  You could even explore their code if you so desired.

Check out these high-profile real-life apps created with Flutter. There’s also a website to showcase and make searchable thousands of apps built with Flutter, some of which are open-source and some of which are templates.

Flutter Architecture

Mobile/Desktop Flutter App:

Web Flutter App:

  • Web rendering options:
    • HTML (HTML, CSS, Canvas, SVG)
    • WebGL (CanvasKit: Skia compiled to WebAssembly)
    • Auto (HTML for mobile, WebGL otherwise)
  • For Web, Dart compiles to JavaScript
  • Semantics widget for accessibility experience

One of the things that makes Flutter architecture unique among cross-platform frameworks is that it brings a rendering layer into the framework itself.  That gives the opportunity to eliminate the inherent UX constraints in either native UI or wrappers for commonalities among multiple platforms of native UI, while also putting more burden on the framework (or community) to provide the necessary building blocks for cross-platform app user experience (UX).

Another thing to notice here is that in Mobile and Desktop targets, Flutter includes the Engine layer, which connects to the device operating system for key functionality and Embedder layer, which handles platform-specific details and connections, whereas in Web targets, the OS is inaccessible, and the only embedding needed is a translation layer into browser-compatible content and interactions.

Flutter Layout

“To perform layout, Flutter walks the render tree in a depth-first traversal and passes down size constraints from parent to child. In determining its size, the child must respect the constraints given to it by its parent. Children respond by passing up a size to their parent object within the constraints the parent established.” – Flutter

“Constraints go down. Sizes go up. Parent sets position.” – Flutter

The tree in this diagram represents the widget tree for the app, where the top is the app’s root widget, and the bottom are the leaves (widgets without children).  This approach allows the layout process to be both efficient and intuitive.

Flutter Usage Approaches

Flutter App:

  • Whole app built using Flutter: “Everything is a widget”
    • App uses and combines Flutter widgets/plugins/packages to accomplish all aspects of the app
    • As desired, create custom widgets at any complexity level, with UI composed by any number of other reusable widgets
    • Any widget can rely on state and rebuild what it renders when state changes
    • State changes can occur from user interaction, completed async tasks or web requests, device sensors, etc.

Flutter Module in Native App:

  • Flutter module imported into existing native Android or iOS app to render a part of the app’s UI in Flutter (or just to run shared Dart logic)
    • App must be restricted to platforms supported by Flutter
    • Support for importing multiple instances of Flutter is a recent addition (3/3/2021)
    • Some non-official efforts have been made to use Flutter for app UI, along with Xamarin.Android/Xamarin.iOS for app structure/packages/viewmodels (Check it out) but it has minimal maintainers

Flutter Development First-Time Basics

  1. Choose desired targets (Android, iOS, Web, macOS, Linux, WPF, UWP)
  2. Choose main Integrated Development Environment (IDE) (Visual Studio Code/Android Studio/IntelliJ)
  3. Set up development machine(s) for desired targets, set up IDE, set up testing devices if applicable
    1. Verify development machine setup with the `flutter doctor` command
  4. Use the IDE to create a new Flutter project (code for new app is in `lib/main.dart`)
  5. Run the app from the IDE on test device(s); emulator(s); browser(s); or desktop app; or any variety of multiple can be configured to launch/run simultaneously, each with hot reload active!
  6. Make code changes while running
    1. There are also contextual assists and macros (snippets) for common actions
    2. VS Code can be configured so “save” or “save all” after changed file causes both auto-reformat and stateful hot reload
  7. Create app widgets, state management, and tests, and find and include desired packages/plugins

Note that step 7 here can be done mostly while the app is running to get immediate insight into the impact of your changes; just hot restart after modifying used packages.

Machine setup instructions: https://flutter.dev/docs/get-started/install

IDE setup instructions: https://flutter.dev/docs/development/tools/vs-code

Instructions for new app creation: https://flutter.dev/docs/get-started/test-drive?tab=vscode

Sources and info on multiple device simultaneous launching/running/debugging:
https://github.com/flutter/flutter/wiki/Multi-device-debugging-in-VS-Code
https://www.jacoboakes.com/flutter_multiple_device_debugging/
https://stackoverflow.com/questions/51669258/flutter-hot-reload-to-multiple-devices

Hot Reload and special cases: https://flutter.dev/docs/development/tools/hot-reload#special-cases

Hello World

This image shows a glimpse at code for a basic Flutter app.

Flutter Development – State Management

Within the bloc package there are entities called blocs and a subset of blocs called cubits.  With a bloc, it receives events via a stream from the UI and sends states via a stream to the UI.  With a cubit, it receives individual calls to its functions from the UI (not via a stream) and sends states via a stream to the UI.

Info about state management in Flutter:
https://flutter.dev/docs/development/data-and-backend/state-mgmt/intro

Sources and additional details about BLoC:
https://www.didierboelens.com/2018/08/reactive-programming-streams-bloc/
https://bloclibrary.dev/ (also source of bloc image)
https://bloclibrary.dev/#/coreconcepts (also source of cubit image)
https://bloclibrary.dev/#/flutterbloccoreconcepts
https://github.com/tenhobi/flashcards/issues/12#issuecomment-373922966 (github issue summarizing a referenced 2018 Dart conference BLoC video's concepts with screenshots and explanations)
https://pub.dev/packages/flutter_bloc/example

Some potentially useful related packages:
https://pub.dev/packages/bloc_code_generator
https://pub.dev/packages/form_bloc

Videos to learn about BLoC in Flutter:
https://www.youtube.com/watch?v=toPtm6eyyeE&list=PLptHs0ZDJKt_T-oNj_6Q98v-tBnVf-S_o&index=3 (Bloc core concepts – streams, blocs, cubits)
https://www.youtube.com/watch?v=NqUx-NfTts4&list=PLptHs0ZDJKt_T-oNj_6Q98v-tBnVf-S_o&index=4 (Flutter Bloc concepts – BlocProvider, BlocBuilder, BlocListener)
https://www.youtube.com/watch?v=kLDfhamoqe0&list=PLptHs0ZDJKt_T-oNj_6Q98v-tBnVf-S_o&index=5 (BLoC architecture - Presentation, Business Logic & Data Layer + Model, Repository, DataProvider)

Detailed explanations and examples using both provider alone and BLoC approaches:
https://www.miquido.com/blog/flutter-architecture-provider-vs-bloc/

Flutter App State Architecture Using BLoC

This is the suggested folder structure for a Flutter App using BLoC for state management.

lib/

    business_logic/

        (optionally: blocs/ and cubits/) - note that the VS Code extension “bloc” uses these folders

    data/

        data_providers/

        models/

        repositories/

    presentation/

        (optionally: animations/ and pages/ and widgets/)

    main.dart

…platform folders, packages configuration, etc.…

To illustrate the data flow for a user interaction that makes a web request, let’s consider a user starting a Flutter App that shows weather for a tapped city, then tapping a button to get the weather for Chicago; the following process occurs.

0) [main.dart] App starts up

1) [presentation] Show initial app state and receive the user interaction when they tap the button for Chicago weather

2) [business_logic] Communicate the Chicago selected event to the business logic component (aka bloc) and the bloc both calls the repository request for the Chicago weather model, and sends a loading weather state to the presentation layer

3a) [presentation] The presentation layer builds and presents the display for the loading weather state

3b) [repositories] The repository request makes a data provider request for a particular data source’s raw data; there may be multiple data providers communicated with during a single repository request

4) [data_providers] The data provider executes the http get web request to a public weather API, and returns the raw response data to the repository code as its result, or throws an exception

5) [repositories] The repository layer handles any failure or uses a factory function on the model class to create a model instance from parsing a specific data source’s format of raw response data.

6) [models] The model factory function creates a model from the raw data

7) [repositories] The repository fine-tunes the model as appropriate and sends it as the response to the bloc

8) [business_logic] The bloc sends either a failure state or a weather loaded state to the presentation layer

9) [presentation] The presentation layer builds and displays the appropriate UI for the new state (either a failure display or the Chicago weather details display)

Folder structure and example flow ideas based on video at:
https://www.youtube.com/watch?v=kLDfhamoqe0&list=PLptHs0ZDJKt_T-oNj_6Q98v-tBnVf-S_o&index=5 (BLoC architecture - Presentation, Business Logic & Data Layer + Model, Repository, DataProvider)

Testing in Flutter using BLoC

  • Use the test and bloc_test packages
    • and optionally the equatable package for “==“ override to comparison by values between instances of types that extend Equatable, which can be good for state objects
  • Create a test/ folder with symmetry to and at the same level as the lib/ folder
    • Create test files with the same folder structure as in lib/, and with matching dart file names, except suffixing the names with “_test” (before “.dart”) – this suffix is what the test package and IDE looks for
  • In any given test file, create a main function, create a group (to group together tests in a named group that may share setup steps)
    • Declare an instance of the type being tested, and create setUp and tearDown functions to create and dispose the instance, passing mocks for dependencies
    • Create test and blocTest functions to test scenarios and specified inputs for expected results
    • Execute a test group in the IDE (“Run” or “Debug” appears above the group), or with command `flutter test`

Testing info based on video - https://www.youtube.com/watch?v=cVru6Gy4duQ&list=PLptHs0ZDJKt_T-oNj_6Q98v-tBnVf-S_o&index=6 (BLoC testing) and - https://pub.dev/packages/bloc_test

Tools to Evaluate and Optimize Flutter Apps

  • DevTools and other language features provided by Dart and Flutter in your IDE
    • Debugger, Memory Profiler, App Size Tool, Hot Restart, Auto Hot Reload on Save, Auto Format Document on Save, Inspect Widget, Observatory Timeline, Network View, Toggle Performance Overlay, Toggle Slow Animations, Toggle Debug Mode Banner, Toggle Repaint Rainbow, Light Bulb code suggestions/fixes, Snippets, Prompts to get packages when out of date, Fix deprecated API’s, Documentation in hovers/tooltips, Go to Definition (Ctrl + Click), Find References,

Also, just as a sidenote, in Dart, access modifiers like private/internal/protected don’t exist, so everything is public, except when a top level or member field identifier starts with underscore, that makes it private to its library, which is by default the dart file it exists in.

Sources regarding DevTools and many other features provided by Dart and Flutter:
https://dartcode.org/
https://dartcode.org/docs/debugging-commands/ (a list of available debugging commands with explanations, also the source for the inspect widget gif)
https://flutter.dev/docs/testing/debugging
https://flutter.dev/docs/development/tools/devtools (collection of links about getting started with the DevTools)
https://flutter.dev/docs/development/tools/devtools/network
https://flutter.dev/docs/development/tools/flutter-fix

Flutter Development – Release Deployments

  • All-in-one option (like Codemagic, Bitrise, Appcircle, App Center): configure and use your selected automated Continuous Delivery (CD) option to deploy to devices for environments prior to production
  • Deployment for Android: create App Bundle > generate Android Package (APK) using bundletool > deploy APK to configured devices using bundletool
    • Production testing options: create App Bundle > upload App Bundle to Google Play > release to internal test track (limited number of internal testers) or to alpha or beta channels to test the production bundle first
  • Deployment for iOS: set up Bundle ID and Application on App Store Connect > create build archive iOS App Store Package (IPA) > Validate and distribute IPA from Xcode (wait 30 mins) > in TestFlight, release to testers (or the App Store)
  • Deployment for Web: build the app for release > deploy `/build/web` folder to cloud hosting
    • Can also be configured to be installable, from a browser viewing the hosted website, as an offline-capable Progressive Web App (PWA)

Sources for release deployments info:
https://flutter.dev/docs/deployment/cd
https://pub.dev/packages/flutter_appcenter_bundle
https://developer.android.com/platform/technology/app-bundle - Android App Bundle (instead of APK)
https://flutter.dev/docs/deployment/android#test-the-app-bundle
https://developer.android.com/studio/command-line/bundletool#deploy_with_bundletool
https://developer.android.com/studio/publish/upload-bundle
https://flutter.dev/docs/deployment/ios
https://flutter.dev/docs/deployment/web

Flutter’s Pros and Cons

Flutter Pros:

  • Beautiful and Flexible UI options and animations
    • Augmented selection of ready-made UI compared to native controls
    • Full control over the rendering stack
    • Composition and declarative UI makes creating custom widgets and reusing widgets easy
  • One codebase can be reused to create an application targeting mobile, web, and desktop
  • Hot Reload blows away competitors with its speed for iterating/collaborating on UX (developer/designer/business analyst (BA)/client)
  • Awesome DevTools
  • Performant rendering
    • Dart language compiles to efficient machine code and/or efficient JavaScript, both Just In Time (JIT) or Ahead Of Time (AOT)
  • Growing in developer cross-platform framework adoption and community support
    • Active Google and open-source contributors
  • Numerous resources to learn Flutter
  • Working with Flutter is enjoyable for developers and collaborators!

Flutter Cons:

  • State management approaches and complexities can be difficult to learn (provider and BLoC are most common)
  • Requires learning Dart language
    • not broadly used outside of Flutter and Google
    • (but Dart does seem intuitive to pick up, has good documentation and learning resources, and IDE’s have several macros for speeding up development)
  • Comparatively immature framework
    • May be difficult early to recruit talent specifically for Flutter or Dart
    • Most Flutter desktop targets still in Alpha or Beta
    • Flutter for Web currently has poor Search Engine Optimization (SEO) capabilities

https://github.com/flutter/flutter/graphs/commit-activity – data showing continued effort and support from Google and open-source contributors for improving Flutter
https://betterprogramming.pub/why-flutter-isnt-the-next-big-thing-e268488521f4 – some downsides to Flutter
https://medium.com/@carlolucera/why-flutter-may-be-the-next-big-thing-15ccf6a9c358 – some counterpoints showing upsides to Flutter
https://medium.datadriveninvestor.com/flutter-engage-flutter-2-2b4e8dde016f – Q&A with Flutter leadership (3/4/2021) with the following quote regarding SEO: “SEO is something we are looking into, but right now if you are building a website that needs SEO, flutter is not a good choice”

Summary

Flutter’s main selling points include:

  • Development efficiency (including an astoundingly powerful hot reload experience, amazing DevTools tooling, and numerous useful macros and quick actions),
  • User interface (UI) beauty and flexibility and ease of customization and animation due its numerous out-of-the-box widgets and its declarative compositional structure,
  • Extensive range of targetable platforms using shared application code, with performant rendering in mobile platforms, desktop platforms, and web, and
  • Extensive development support and library of packages and plugins from Google and open-source contributors.

Also noteworthy, though mostly a side effect of the above points, Flutter has a very high and growing adoption among the cross-platform development community.

If you’re considering giving Flutter development a try, do it.  Flutter is here to stay, and my bet is that you’ll enjoy creating with it, and you’ll be happy with the UI you can create, and you’ll be happy how quickly you can iterate on changes.  You may even enjoy learning about it, considering the variety of resources that teach about it.
Thanks for reading, and I hope I helped you learn something new.

Helpful Resources