Understand Flutter's UI Approach
Prerequisites include a Flutter installation with VS Code or Android Studio and knowledge of setting up a Flutter project.
Get a brief overview of how Flutter approaches UI creation using the declarative approach and how it compares to its native counterparts.
Flutter is a UI framework for creating beautiful mobile, desktop and web applications all from a single codebase.
You code your UI using the dart programming language instead of using an interface builder or XML. To build UIs, you simply use a widget. Widgets are classes that holds the user interfaces and sometimes the state of the widget. In other words, widgets are the building blocks of Flutter applications.
Historically, native apps have always been created in an imperative fashion. Meaning, your UI is updated based on a sequence of events in a step by step manner.
So when working with something like a label and there is a change in your model or data, you’ll have to tell the UI or view to set the text on a label to the new value.
On the other hand, Flutter uses a declarative approach in building UIs. Here, your UI is simply the result of a function that processes the changes in a state. That means your UI is updated based on changes in the state. In other words, when your state changes, Flutter automatically updates the UI.
Flutter favors composition over inheritance which means that widgets are composed of other widgets. This results in a tree-like structure. So a Flutter app is just a tree of widgets and each app screen is a sub-tree in the entire widget tree.
Every widget has a build method which takes the data in a widget and returns a composition of widgets which describes the user interfaces. The build method is called whenever the widget is inserted in the tree or when the dependencies of the widget changes.
You can create stateless or stateful widgets. Stateless widgets are simply widgets in which its properties don’t change. Meaning, its properties are fixed and cant be changed by the widget itself. It can only rebuild its contents when the parent widget passes a new value to its properties. This process destroys the stateless widget and recreates it with the new properties.
A simple example could be a text widget to display the app’s name on the app bar. This could be a stateless widget since the app name would not need to be updated while using the app. On the other hand, Stateful widgets have a mutable state. This simply means that the widget can internally change its properties to trigger a rebuild.
An example could be a news feed card widget which has a ‘like’ or ‘react’ button. Pressing the button would trigger the ‘total_likes’ state member to change which in turn rebuilds the widget with the new ‘total_likes’.
Remember, all this happens in a declarative way, meaning widgets are updated when it’s state changes. So, which widget should you use? Well, a rule of thumb is: always start with a stateless widget then if the need arises to manage local state, then you convert it to a stateful widget.
So does this mean that Android and iOS doesn’t support the declarative approach to building UIs? Well, over the years, the declarative approach of building UIs has gained popularity with libraries like React and mobile frameworks like React Native. The native app ecosystem has also followed this trend because there is no doubt that UI creation is heading more towards the declarative side.
Android and iOS have created Jetpack Compose and SwiftUI respectively to let native developers benefit from the gains of building app UIs declaratively. Do note that SwiftUI only works for iOS 13 apps and up. Do your apps wont work on older devices :(
On the other hand, Flutter is a cross platform framework used for building apps for mobile, web and desktop all from a single codebase. And it is definately a good framework to dive into the ocean of declarative UI development.
This course explores various commonly used UI widgets provided by Flutter and I can’t wait to get started. So go ahead and grab a cup of coffee and I’ll see you in the next episode.