感君一回顧,思君朝與暮。
<一>StatelessWidget
- 一旦構(gòu)建后狀態(tài)就不能改變的Widget。這些Widget一旦被構(gòu)建就是不可變的,即變量、圖標、按鈕或數(shù)據(jù)的任何變化都不能改變Widget的狀態(tài)。一些官方的實例:Text、RaisedButton、Icon。以下是StatelessWidget的基本寫法:
class SplashScreen extends StatelessWidget { const SplashScreen({Key? key}) : super(key: key); // This widget is the root of your application. @override Widget build(BuildContext context) { return Container(color: Colors.red); } } - StatelessWidget 的build方法并返回一個Widget,其中Widget的狀態(tài)不會在運行時發(fā)生改變,只會在初始化的是才賦與值。
1.無狀態(tài)組件是StatelessWidget組件。
2.它們不依賴于任何數(shù)據(jù)或行為發(fā)生更改。
3.Stateless Widgets 沒有狀態(tài),它們只會被渲染一次并且不會自我更新,只會在外部初始化的時候進行更新。
4.例如:Text、Icon、RaisedButton是無狀態(tài)組件。
<二> StatefulWidget
- 是一旦構(gòu)建Widget的狀態(tài)還會發(fā)生改變的Widget。這些state是可變的,并且可以在其生命周期中多次改變。這只是意味著Widget狀態(tài)可以通過不同的變量、輸入、或數(shù)據(jù)的任何變化都可能改變Widget的狀態(tài)。官方的一些示例:CheckBox、RadioButton、Form、TextField。以下是StatefulWidget的基本寫法:
class MyApp extends StatefulWidget { @override _MyAppState createState() => _MyAppState(); } class _MyAppState extends State<MyApp> { @override Widget build(BuildContext context) { return Container(); } } - StatefulWidget覆蓋createState() 并返回一個State。
<三>StatefulWidget 的生命周期
- createState()
當我們創(chuàng)建一個有狀態(tài)的組件時,F(xiàn)lutter框架會提示創(chuàng)建 createState() 方法。@override _MyAppState createState() => _MyAppState(); - mounted
一旦我們創(chuàng)建了一個State對象,框架就會通過在調(diào)用initState()方法之前將它與BuildContext來mounted一個State對象。所有組件都具有 bool mounted屬性。當 buildContext 被分配時,它變成true。bool get mounted => _element != null; - initState
這是在類構(gòu)造函數(shù)之后創(chuàng)建有狀態(tài)小部件時調(diào)用的第一個方法。initState() 只調(diào)用一次。它必須調(diào)用 super.initState()。在這里,您可以初始化數(shù)據(jù)、屬性并訂閱 Streams 或任何其他可以更改此小部件上數(shù)據(jù)的對象。@override initState() { super.initState(); //... } - didChangeDependencies
在第一次構(gòu)建組件時在 initState() 方法之后立即調(diào)用此方法,每當調(diào)用此組件所依賴的數(shù)據(jù)的對象時,它也會被調(diào)用。例如:它依賴于更新的 InheritedWidget。build 方法總是在調(diào)用 didChangeDependencies 之后調(diào)用,因此很少需要這樣做。@override void didChangeDependencies() { // TODO: implement didChangeDependencies super.didChangeDependencies(); } - build
它顯示由組件表示的用戶界面部分。在幾種不同的情況下調(diào)用此方法:
1.調(diào)用 initState() 方法后。
2.框架總是在調(diào)用 didUpdateWidget 后調(diào)用 build() 方法
3.收到 setState 調(diào)用后更新UI。@override Widget build(BuildContext context) { return Container(); } - didUpdateWidget
如果父組件更改配置并且必須重建此組件。但是它正在使用相同的 runtimeType 重建,然后調(diào)用 didUpdateWidget() 方法。更新此狀態(tài)對象的組件屬性以引用新的組件,然后使用前一個組件作為參數(shù)調(diào)用此方法@override void didUpdateWidget(covariant MyHomePage oldWidget) { // TODO: implement didUpdateWidget super.didUpdateWidget(oldWidget); } - setState
當用戶執(zhí)行setState方法時,當執(zhí)行setState方法里面需要實現(xiàn)的回調(diào)函數(shù)后,將會再次執(zhí)行build方法更新反映在 UI 中。setState 通知框架當前對象的內(nèi)部狀態(tài)已以可能影響用戶界面的方式更改。@override void setState(VoidCallback fn) { // TODO: implement setState super.setState(fn); } - deactivate
當從組件樹中刪除狀態(tài)時調(diào)用,但它可能會在當前幀更改完成之前重新插入。之所以存在此方法,是因為 State 對象可以從樹中的一個點移動到另一個點。@override void deactivate() { // TODO: implement deactivate super.deactivate(); } - dispose
當State對象被永久移除時調(diào)用。在這里您可以取消訂閱和取消所有動畫、流等。
1.有狀態(tài)組件是StatefulWidget組件。@override void dispose() { // TODO: implement dispose super.dispose(); }
2.可以在運行時根據(jù)用戶操作或數(shù)據(jù)更改進行更新。
3.有狀態(tài)的 Widget 有一個內(nèi)部狀態(tài),如果輸入數(shù)據(jù)發(fā)生變化或 Widget 的狀態(tài)發(fā)生變
化,它可以重新渲染。
4.例如:復選框、單選按鈕、滑塊是有狀態(tài)的組件
<四>總結(jié)
- 無狀態(tài)的含義僅僅是組件的所有屬性都是不可變的。所以能夠更改StatelessWidget的唯一方法是該StatelessWidget的初始化。總結(jié)的來說一個StatelessWidget將永遠不會自行重建,但它可以從外部去初始化。而StatefulWidget可以自己觸發(fā)重建,比如通過調(diào)用setState()。