Skip to content

Commit 12500fc

Browse files
committed
Add page widget class info
1 parent d2c3536 commit 12500fc

File tree

3 files changed

+150
-68
lines changed

3 files changed

+150
-68
lines changed

docs/generated-code/page-model.md

Lines changed: 0 additions & 67 deletions
This file was deleted.
Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
---
2+
title: Pages
3+
slug: /generated-code/page-model
4+
sidebar_position: 4
5+
---
6+
7+
# Generated Code: Pages
8+
9+
When you create a new page in FlutterFlow, it automatically generates two files: a `Widget` class and a `Model` class. So if the name of the page you created is called ProductListPage, FlutterFlow generation backend will automatically create ProductListPageWidget class and ProductListPageModel class.
10+
11+
:::info[Prerequisites]
12+
This guide uses example of the generated code of the **[EcommerceFlow demo app](https://bit.ly/ff-docs-demo-v1)**. To view the generated code directly, check out the **[Github repository](https://github.com/FlutterFlow/sample-apps/tree/main/ecommerce_flow)**.
13+
:::
14+
15+
## PageModel class
16+
17+
The `PageModel` classes are responsible for managing the state of individual pages and initializing the components used in these Pages. These classes extend the `FlutterFlowModel` class, which provides a consistent structure and shared functionality across all page models.
18+
19+
#### Managing Local State
20+
21+
A `PageModel` class typically holds local state fields specific to the page, which correspond to the **[Page State variables](../resources/ui/pages/page-lifecycle.md#page-state)**.
22+
23+
For example, in the ProductListPage, user may create a Page State variable called `searchString`. Correspondingly, in the `product_list_page_model.dart` [file](https://github.com/FlutterFlow/sample-apps/blob/main/ecommerce_flow/lib/product/product_list_page/product_list_page_model.dart) (which is the `Model` file for the `ProductListPage`), the corresponding state field would be `_searchString`. This private field stores the current search string and includes a getter and setter to manage its value while logging any changes.
24+
25+
```js
26+
String? _searchString;
27+
set searchString(String? value) {
28+
_searchString = value;
29+
debugLogWidgetClass(rootModel);
30+
}
31+
String? get searchString => _searchString;
32+
```
33+
34+
:::tip[Private variables in Dart]
35+
In Dart, variables that start with an underscore (`_`), such as `_searchString`, are private to the class. This means they cannot be accessed outside the class or its scope.
36+
:::
37+
38+
In addition to managing local state, the given `PageModel` class also contains fields for handling the state of widgets on the page. For instance, `_dropDownValue` is a private field that stores the current value of a dropdown widget (if it is added to the current Page). Similar to `_searchString`, it has a getter and setter that logs changes to this field.
39+
40+
```js
41+
String? _dropDownValue;
42+
set dropDownValue(String? value) {
43+
_dropDownValue = value;
44+
debugLogWidgetClass(rootModel);
45+
}
46+
String? get dropDownValue => _dropDownValue;
47+
```
48+
49+
#### Initializing child component models
50+
The `PageModel` class is also responsible for initializing the models of components used on the page. For example, if the page includes a `CartCounter` component, the model for this component is initialized within the page's model class.
51+
52+
```js
53+
// Model for CartCounter component.
54+
late CartCounterModel cartCounterModel;
55+
56+
@override
57+
void initState(BuildContext context) {
58+
cartCounterModel = createModel(context, () => CartCounterModel()..parentModel = this);
59+
60+
}
61+
```
62+
:::info
63+
Only the model class of a child component is initialized inside the page or parent model class. In the case of page model classes, they are initialized within the widget’s state class itself. See the **[Widget class section](#pagewidget-class)** for more details.
64+
:::
65+
66+
When dealing with dynamic lists of components, such as those in a `ListView`, Row, or Column widget, the `PageModel` initializes a `Map<String, FlutterFlowModel>` to manage the state of each component instance. For example, if the page includes a list of `CategoryAvatar` components, the initialization might look like this:
67+
68+
```js
69+
// Models for CategoryAvatar dynamic component.
70+
Map<String, FlutterFlowModel> categoryAvatarModels = {};
71+
72+
```
73+
74+
#### dispose()
75+
76+
Finally, the `dispose` function in the `ProductListPageModel` class is used to clean up resources when they are no longer needed. This is a common practice in Flutter to prevent memory leaks. In this class, the `dispose` function is overridden to dispose of the `cartCounterModel`, `searchQueryFocusNode`, and `searchQueryTextController`.
77+
78+
```js
79+
80+
@override
81+
void dispose() {
82+
cartCounterModel.dispose();
83+
searchQueryFocusNode?.dispose();
84+
searchQueryTextController?.dispose();
85+
}
86+
```
87+
88+
89+
## PageWidget class
90+
91+
The `PageWidget` classes are responsible for creating the UI of individual pages and holding the widget tree as designed in the FlutterFlow canvas. These classes always extend Flutter's `StatefulWidget` class utilizing Flutter's built-in state management through `setState` to handle dynamic updates and interact with the app's lifecycle.
92+
93+
```js
94+
class OrderListPageWidget extends StatefulWidget {
95+
const OrderListPageWidget({
96+
super.key,
97+
98+
});
99+
100+
final int? productId;
101+
102+
103+
@override
104+
State<OrderListPageWidget> createState() =>
105+
_OrderListPageWidgetState();
106+
}
107+
108+
```
109+
110+
#### Route Awareness
111+
In the generated code, FlutterFlow automatically includes the `RouteAware` mixin in the **State** class. This makes the page aware of changes in the navigator's session history, allowing it to handle lifecycle events such as when the page becomes visible again after being removed.
112+
113+
```js
114+
class _OrderListPageWidgetState extends State<OrderListPageWidget>
115+
with RouteAware {
116+
```
117+
118+
#### PageModel Initialization
119+
Additionally, the `PageModel` class is initialized within the state class. This class serves as a centralized place to manage the page’s state, handle business logic, and interact with the data layer.
120+
121+
```js
122+
class _OrderListPageWidgetState extends State<OrderListPageWidget>
123+
with RouteAware {
124+
late OrderListPageModel _model;
125+
```
126+
127+
#### Global Scaffold Key
128+
Each page includes a `GlobalKey` for the `Scaffold`, which can be used to manage the scaffold's state, such as opening or closing drawers or snackbars programmatically.
129+
130+
```js
131+
final scaffoldKey = GlobalKey<ScaffoldState>();
132+
133+
return Scaffold(
134+
key: scaffoldKey,
135+
...)
136+
```
137+
138+
#### Keyboard Dismissal
139+
Moreover, the root widget of every page is a `GestureDetector` with an `onTap` callback that unfocuses the current input field. This ensures that any active keyboard is dismissed when tapping outside an input field, improving the user experience across pages.
140+
141+
```js
142+
return GestureDetector(
143+
onTap: () => FocusScope.of(context).unfocus(),
144+
child: Scaffold(
145+
...)
146+
```
147+
148+
These functionalities are automatically added by FlutterFlow to ensure seamless navigation and proper keyboard handling across pages.
149+

docs/resources/ui/pages/intro-pages.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ Whether you're starting from scratch, using a template, or leveraging AI tools,
2828
there are several pathways to achieve the desired functionality and aesthetic of your desired Page.
2929

3030
:::tip[Generated Code]
31-
When you create a page in FlutterFlow, a `Widget` class and a corresponding `Model` class are automatically generated. You can view these in the Code Viewer. To explore the details of the generated `Model` class, take a closer [**look at the code**](../../../generated-code/page-model.md).
31+
When you create a page in FlutterFlow, a `Widget` class and a corresponding `Model` class are automatically generated. You can view these in the Code Viewer. To explore the details of the generated `Model` class, take a closer [**look at the code**](../../../generated-code/pages-generated-code).
3232
:::
3333

3434
FlutterFlow allows you to easily create new pages using the **Add Page, Component, or Flow** button,

0 commit comments

Comments
 (0)