Flutter的生命週期
Flutter主要有兩種:無狀態的 StatelessWidget和有狀態的 StatefulWidget
1. StatelessWidget
一個 StatelessWidget 是不能被改變的,比如:Icon、Text等。由於不可改變,因此並沒有什麼生命週期。
2. StatefulWidget
一個 StatefulWidget 是有狀態的,可變的。一個 StatefulWidget 元件可以通過定義它的 State 來進行對元件資料狀態的儲存和修改。那麼它的State應該是有一系列的生命週期。
上圖就是 State 的生命週期圖。
-
StatefulWidget.createState()Framework 呼叫會通過呼叫 StatefulWidget.createState() 來建立一個 State。
-
initState()新建立的 State 會和一個 BuildContext 產生關聯,此時認為 State 已經被安裝好了,initState() 函式將會被呼叫。通常,我們可以重寫這個函式,進行初始化操作。
-
didChangeDependencies()在 initState() 呼叫結束後,這個函式會被呼叫。事實上,當 State 物件的依賴關係發生變化時,這個函式總會被 Framework 呼叫。
-
build()經過以上步驟,系統認為一個 State 已經準備好了,就會呼叫 build() 來構建檢視。我們需要在這個函式中,返回一個 Widget。
-
deactivate()當 State 被暫時從檢視樹中移除時,會呼叫這個函式。頁面切換時,也會呼叫它,因為此時 State 在檢視樹中的位置發生了變化,需要先暫時移除後新增。
⚠️注意,重寫的時候必須要呼叫 super.deactivate()。
-
dispose()當 State 被永久的從檢視樹中移除,Framework 會呼叫該函式。在銷燬前觸發,我們可以在這裡進行最終的資源釋放。在呼叫這個函式之前,總會先呼叫 deactivate()。
⚠️注意,重寫的時候必須要呼叫 super.dispose()。
-
didUpdateWidget(covariant T oldWidget)當 widget 的配置發生變化時,會呼叫這個函式。比如,Hot-reload 的時候就會呼叫這個函式。這個函式呼叫後,會呼叫 build()。
-
setState()當我需要更新 State 的檢視時,需要手動呼叫這個函式,它會觸發 build() 。
Flutter的路由
Flutter裡面的路由主要是通過Navigator這個類進行控制的,當你想從這個頁面跳到另外一個頁面的時候,通過Navigator即可 ⚠️呼叫的時候要注意頁面是入棧操作,千萬別累積了太多的頁面
這裡為了更加直觀的展示路由之間的跳轉和轉換,我將我專案裡面封裝的一個NavigatorUtils的程式碼展現出來
import 'dart:async';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_xinqiu/page/home_page.dart';
import 'package:flutter_xinqiu/page/login_page.dart';
import 'package:flutter_xinqiu/page/noob_setting_page.dart';
import 'package:flutter_xinqiu/page/user_idea_page.dart';
import 'package:flutter_xinqiu/widget/custom_route.dart';
/**
* 路由跳轉
* Created by xiaocheng123
* Date: 2019-7-8
*/
class NavigatorUtils {
///替換
static pushReplacementNamed(BuildContext context, String routeName) {
Navigator.pushReplacementNamed(context, routeName);
}
///切換無引數頁面
static pushNamed(BuildContext context, String routeName) {
Navigator.pushNamed(context, routeName);
}
///主頁
static goHome(BuildContext context) {
Navigator.pushReplacementNamed(context, HomePage.sName);
}
///登入頁
static goLogin(BuildContext context) {
// Navigator.pushReplacementNamed(context, LoginPage.sName);
Navigator.of(context).pushAndRemoveUntil(
new MaterialPageRoute(builder: (context) => new LoginPage()
), (route) => route == null);
}
///新手設定頁面
static goNoobSetting(BuildContext context) {
Navigator.of(context).push(CustomRoute(NoobSettingPage()));
}
///意見反饋設定頁面
static goUserIdea(BuildContext context) {
Navigator.push(context,
new CupertinoPageRoute(builder: (context) => pageContainer(UserIdeaPage())));
}
///公共開啟方式
static NavigatorRouter(BuildContext context, Widget widget) {
return Navigator.push(context,
new CupertinoPageRoute(builder: (context) => pageContainer(widget)));
}
///Page頁面的容器,做一次通用自定義
static Widget pageContainer(widget) {
return MediaQuery(
///不受系統字型縮放影響
data: MediaQueryData.fromWindow(WidgetsBinding.instance.window)
.copyWith(textScaleFactor: 1),
child: widget);
}
}
複製程式碼
在程式碼裡面可以將跳轉到某個路由進行封裝起來,這樣進行路由跳轉的時候直接引用即可