I help you get started with Google’s Flutter, the most popular cross-platform UI toolkit for building native mobile, desktop, and web applications.
Use React Native.
The Flutter website is an excellent place to get familiar with Flutter. Flutter uses the Dart programming language to create natively-compiled applications for mobile, web, desktop & embedded. Both Flutter and Dart can use plugins that have [a great portal]((#plugin-portal).
You start with the Dart language tour. Java developers take the “Intro to Dart for Java Developers” next. Then you have options:
Here are the instructions, straight from the Flutter website:
Flutter uses a declarative approach to build UIs. I have a page dedicated to declarative UIs. Please check it out!
Here’s a selection of Flutter tutorials and courses:
Flutter doesn’t use native UI elements (such as text fields or buttons). Instead, it emulates them. Flutter uses the Google open-source Skia Graphics library for that. Chrome and Firefox, Chrome OS, and Android also use Skia. But this also means Flutter only paints pixels: It has to recreate all native iOS/Android UI elements in Flutter. Flutter calls the UI elements “widgets”. Out of the box, Flutter has two widget sets:
flutter_cupertino_settings can fill this void.By default, we manually have to switch between these two widget sets in our code: Pick a Cupertino widget on iOS/iPadOS and a Material one everywhere else. flutter_platform_widgets does that for us.
There are two open-source widget sets that provide widgets with native look & feel for Windows and macOS: fluent_ui and macos_ui.
According to Flutter, a responsive app changes with the screen size and orientation. An adaptive app changes with device type (mobile & desktop) and input type (keyboard & mouse vs. touch).
From what I can tell, the advice for a responsive app is to check the screen width and then update the UI. That seems like a primitive solution compared to other approaches. The web, for instance, has the Bootstrap Grid, CSS Flexbox, and CSS Grid. Android has size classes, as does iOS.
I’ve used flutter_bootstrap for responsive layout on mobile.
I built a sample Flutter application with five different, native “Look & Feels” with one codebase: Web, iOS, Android, Windows, and Mac. Here are screenshots from the form screen of that application which demonstrate the differences well.
Web
iOS
Android
Windows
macOS
The source code for this project is on Github:
You need Flutter to run the application. Please find the installation instructions above. The Flutter installation instructions also tell you which additional tools you need. That’s typically IDEs, such as Android Studio, Visual Studio for Windows, or Apple’s Xcode.
Here’s which platforms you can run. That depends on your development machine operating system:
web, ios, android, windows, macos, and linux.lib folder. It has two folders: ui contains the home page widget and the three screens. shared has cross-platform, native widgets, like button, text field, or even an entire app.build() method has an switch statement that calls platform-specific methods to build the widget. Here’s the button build() method.shared folder also contains service classes for device & display and some domain classes.main.dart is the entry point of the application. It opens the home page which shows three screens: InfoPage, FormPage, and SettingsPage.SDevice._setCurrentPlatform() which forces CrossApp to rebuild the UI.The best code is the one we don’t have to write. That’s why we’d like to use open-source libraries in our apps. In Flutter, they are called plugins. Please see the “Plugins (Libraries)” section below.
“Don’t repeat yourself” (DRY) is a valuable software development principle. It generally leads to apps that are easier to maintain. Applying DRY means that we create our own components. There are two prime candidates for that in Flutter:
I suggest structuring an application with horizontal and vertical layers. That makes it easier to manage in the long run. “Manage” means fixing bugs and adding features. But “manage” also means “Where the heck is the code that does X?!”.
Let’s start with vertical layers. We can imagine them as columns in our architecture.
We can also have horizontal layers, the rows in our architecture.
I use Redux as my global data store. When that store changes, my UI refreshes. That helps avoiding UI inconsistencies. And that local state helps my app work when it’s offline.
Redux started in the web world. In Flutter, I persist my state as JSON. I use flutter_redux, redux_persist_flutter, and redux_persist.
Here’s a complete tutorial. Please note, unlike what we see in that tutorial, our code can refresh widgets if just parts of the Redux store change. In the example below, the widget only rebuilds if the current users changes:
|
|
Flutter Hot Reload makes code changes go live in the device/simulator within a second. It’s the main reason why working with Flutter can be such fun! I mentioned it in the talk. Here is a video demonstrating it.
Flutter Hot Restart gets the app back into its initial state. That takes 3-5 seconds on my M1 Max MacBook Pro.
The Flutter plugin portal is awesome! It gives you example code, popularity metrics, and code quality information.
Here is the main plugin page:
This is the changelog:
Here is an example program:
Here is the version list:
The score screen tells us about the code quality of the plugin:
Sometimes, there’s a bug in a Flutter plugin. Or we need a feature that a plugin doesn’t have. Then we can fork the plugin easily in Git. Please note that the plugin’s license needs to be compatible with forking.
Once we have the plugin forked, we don’t need to publish it. Instead, we can use the fork’s Git repository URL directly in the build file. Here’s how. Sweet!