Creating User Interfaces with Flutter
2 Flutter Knowledge Base
2.1 Widgets
Flutter is a reactive, declarative, and composable library for building user interfaces, similar to ReactJS, but with a key difference—Flutter includes its own complete rendering engine. In essence, you create mobile UIs by composing smaller components known as widgets. Everything in Flutter is a widget, which are simply Dart classes responsible for describing their views. Widgets define the structure, styles, animations, and every other aspect of the UI.

Everything in Flutter consists of widgets inside widgets inside widgets. Some widgets maintain state: for example, a quantity widget that tracks how many items to add to the cart. When a widget’s state changes, the framework is notified and compares the new widget tree description to the previous one, updating only the necessary widgets. In the case of the cart example, when a user presses the "+" button on the quantity widget, it updates its internal state, signaling Flutter to repaint all widgets that depend on that state (such as the text widget). Figure 1.4 illustrates a wireframe of the widgets before and after pressing the "+" IconButton.

A widget in Flutter can define any aspect of an application’s view. Some widgets, like Row, define layout properties, while others, like Button and TextField, define structural elements. Even the root of the application itself is a widget.
For reference, here are some of the most common types of widgets:
-
Layout —
Row,Column,Scaffold,Stack -
Structural —
Button,Toast,MenuDrawer -
Styling —
TextStyle,Color -
Animations —
FadeInPhoto, transformations -
Positioning and Alignment —
Center,Padding

2.2 Flutter App Classes: MaterialApp, CupertinoApp, and WidgetsApp
Flutter offers different foundational app classes, each suited for specific design languages and use cases. The primary classes are MaterialApp, CupertinoApp, and WidgetsApp. Each of these classes provides a different set of functionalities and design principles, catering to diverse platform needs.
2.2.1 MaterialApp
Definition: MaterialApp is a high-level app class in Flutter that is built on top of WidgetsApp. It incorporates Google’s Material Design language and offers a comprehensive set of widgets and features designed to follow Material Design guidelines.
Use Case: It is the go-to class for apps that are built to follow Material Design, making it ideal for Android apps or Flutter apps targeting multiple platforms where Material Design consistency is desired.
Features:
-
Provides Material Design-specific widgets such as
Scaffold,AppBar,FloatingActionButton, etc. -
Includes theme management through
ThemeDatafor easy customization of the look and feel of the app. -
Supports advanced routing and navigation features.
-
Ensures visual consistency across different devices by adhering to Material Design principles.
2.2.2 CupertinoApp
Definition: CupertinoApp is another app class in Flutter, specifically designed to provide an iOS-style user interface. It adheres to Apple’s Human Interface Guidelines and includes Cupertino-style widgets.
Use Case: This class is used when building apps that target iOS or when an iOS look and feel is required across platforms. It provides Cupertino (iOS) specific components and designs for a native iOS experience.
Features:
-
Offers Cupertino widgets such as
CupertinoNavigationBar,CupertinoTabBar,CupertinoButton, etc. -
Provides an iOS-themed UI with support for native-style transitions, navigation, and gestures.
-
Uses iOS-specific designs, making it ideal for apps where platform fidelity on iOS is a key requirement.
-
Supports iOS-style routing and navigation patterns.
2.2.3 WidgetsApp
Definition: WidgetsApp is a lower-level foundational class in Flutter that provides the basic structure and functionality for any Flutter app. Unlike MaterialApp and CupertinoApp, WidgetsApp does not enforce any design language, allowing for complete custom UI development.
Use Case: It is used when an app requires a fully custom design that does not follow Material or Cupertino guidelines. Developers can use WidgetsApp to build entirely custom UIs from scratch.
Features:
-
Provides core functionality such as navigation, localization, and rendering of widgets.
-
Does not include predefined widgets for any specific design language (like Material or Cupertino).
-
Suitable for custom apps that require flexibility in the user interface without adhering to predefined design systems.
-
Supports accessibility, localization, and other basic app features.
2.2.4 Key Differences
-
Design Language:
MaterialAppsupports Google’s Material Design,CupertinoAppsupports Apple’s iOS design guidelines, whileWidgetsAppis design-agnostic. -
Use Cases:
MaterialAppis used for apps that follow Material Design,CupertinoAppis for iOS-style apps, andWidgetsAppis for fully custom-designed apps. -
Widget Set:
MaterialAppandCupertinoAppcome with a rich set of pre-built widgets for their respective design languages, whileWidgetsAppprovides only the core framework without pre-built design-specific widgets. -
Platform Fidelity:
CupertinoAppis tailored for iOS platform fidelity, whileMaterialAppis for apps that need consistent Material Design across platforms.
2.2.5 Summary
In Flutter, choosing between MaterialApp, CupertinoApp, and WidgetsApp depends on the specific design requirements and the platforms you are targeting. For Material Design-based apps, MaterialApp is the best choice, whereas CupertinoApp should be used for apps requiring an iOS-style UI. If you require a custom design or don’t need predefined design elements, WidgetsApp is the most flexible option.
2.2.6 PlatformApp
Flutter offers another app class called PlatformApp, which is used in conjunction with libraries like flutter_platform_widgets. This class provides a way to dynamically switch between Material and Cupertino styles based on the platform (iOS or Android).
Definition: PlatformApp is a wrapper provided by third-party libraries such as flutter_platform_widgets. It allows developers to create apps that automatically adjust their design and components according to the platform on which they are running (iOS or Android). It bridges the gap between MaterialApp and CupertinoApp, offering a hybrid approach that adapts to the platform at runtime.
Use Case: This class is ideal for apps that need to maintain a consistent user experience across platforms while adapting to each platform’s native design language. For instance, it enables an app to use Material widgets on Android and Cupertino widgets on iOS without writing separate code for each platform.
Features:
-
Dynamically switches between Material and Cupertino widgets depending on the platform.
-
Provides platform-aware components that adhere to the native look and feel of Android and iOS.
-
Supports both Material and Cupertino design guidelines in a single app, making it easy to target multiple platforms with minimal effort.
-
Simplifies code maintenance by avoiding the need for conditionally rendering different UI elements for each platform.
2.3 Flutter Widgets: Stateless vs Stateful
In Flutter, the fundamental building blocks of the UI are widgets. Widgets can be categorized into two types: StatelessWidget and StatefulWidget. Understanding the differences between these two types is crucial for developing Flutter applications.
2.3.1 StatelessWidget
Definition: A StatelessWidget is a widget that does not maintain any mutable state. Once created, it remains the same throughout its lifecycle. It is used when the UI does not need to change dynamically after it is built.
Use Case: StatelessWidget is typically used for static content or UI components that do not depend on user interaction or dynamic data. For example, a static screen with only text and images would be a good candidate for a StatelessWidget.
Features:
-
StatelessWidgetis immutable. Once created, it cannot change its properties or re-render itself. -
It is simple and lightweight since it doesn’t involve state management.
-
The widget’s build method is only called once during the widget’s lifecycle.
Example:
class MyStatelessWidget extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Text('Hello, World!');
}
}
2.3.2 StatefulWidget
Definition: A StatefulWidget is a widget that can rebuild itself in response to state changes. It has mutable state that can be updated during its lifecycle, causing the widget to re-render.
Use Case: StatefulWidget is used when the UI needs to change dynamically based on user interactions, input, or asynchronous data. For example, buttons that change appearance when pressed, forms that display validation messages, or data fetched from an API are cases where a StatefulWidget would be necessary.
Features:
-
StatefulWidgetis mutable, allowing it to hold dynamic state and update itself. -
It consists of two parts: the
StatefulWidgetitself and a separateStateclass that manages the widget’s state. -
The widget can rebuild itself whenever its state changes using the
setState()method.
2.3.3 Key Differences
-
State Management:
StatelessWidgetcannot manage state, whileStatefulWidgetcan manage and update its state dynamically. -
UI Updates:
StatelessWidgetis static and cannot change after being built. In contrast,StatefulWidgetcan rebuild itself in response to state changes using thesetState()method. -
Lifecycle:
StatelessWidgethas a simpler lifecycle, where the widget is built once.StatefulWidget, on the other hand, involves the creation and management of a separate state object that can trigger rebuilds during the widget’s lifetime. -
Complexity:
StatefulWidgetis generally more complex to implement due to the need to manage the state, whileStatelessWidgetis simpler and more efficient when dynamic changes are not required.
2.3.4 When to Use Which
StatelessWidget should be used when the UI is static, and no interaction will change its appearance or behavior. It is ideal for components like static headers, labels, or simple layouts.
StatefulWidget is necessary when the widget needs to react to user inputs, asynchronous data changes, or any other event that alters the UI. It is appropriate for forms, animations, counters, or any interactive component.
2.3.5 Summary
The choice between StatelessWidget and StatefulWidget depends on whether the widget’s UI will change dynamically over time. Understanding these two types of widgets allows developers to optimize performance and manage state effectively in Flutter applications.
2.4 BuildContext in the build() Function
In Flutter, the BuildContext parameter in the build function provides a way for a widget to interact with its location in the widget tree. BuildContext is an object that represents the location of a widget in the widget tree. It allows a widget to access information about its parent, child, and surrounding context.
2.5 Scaffold
Scaffold provides a framework for implementing the basic visual layout structure of Material Design applications. It includes support for app bars, drawers, bottom navigation bars, floating action buttons, and snack bars. It simplifies the management of common UI elements and provides a consistent layout.
You do not have to use a Scaffold in every Flutter application, but it is highly recommended for certain types of applications, especially those that follow the Material Design guidelines.