在這篇文章中,將帶着你們一塊兒認識什麼是StatelessWidget?
,什麼是StatefulWidget?
,以及StatefulWidget和StatelessWidget都有哪些最佳實踐?
ios
狀態是在構建widget時能夠同步讀取的信息,或者在widget的生命週期中可能更改的信息,在Flutter中若是要管理狀態須要用到 StatefulWidget。app
Flutter中的StatelessWidget
是一個不須要狀態更改的widget - 它沒有要管理的內部狀態。框架
當您描述的用戶界面部分不依賴於對象自己中的配置信息以及widget的BuildContext 時,無狀態widget很是有用。less
AboutDialog
, CircleAvatar
和 Text
都是StatelessWidget
的子類。異步
// Flutter
import 'package:flutter/material.dart';
void main() => runApp(MyStatelessWidget(text: "StatelessWidget Example to show immutable data"));
class MyStatelessWidget extends StatelessWidget {
final String text;
MyStatelessWidget({Key key, this.text}) : super(key: key);
@override
Widget build(BuildContext context) {
return Center(
child: Text(
text,
textDirection: TextDirection.ltr,
),
);
}
}
複製代碼
以上代碼片斷的完整部分能夠在課程源碼中查找。ide
在前面的示例中,您使用了MyStatelessWidget類的構造函數 傳遞標記爲final的text。這個類繼承了StatelessWidget-它包含不可變數據函數
無狀態widget的build方法一般只會在如下三種狀況調用:佈局
StatefulWidget 是可變狀態的widget。 使用setState
方法管理StatefulWidget的狀態的改變。調用setState
告訴Flutter框架,某個狀態發生了變化,Flutter會從新運行build方法,以便應用程序能夠應用最新狀態。動畫
狀態是在構建widget時能夠同步讀取的信息可能會在widget的生命週期中發生變化。確保在狀態改變時及時通知狀態 變化是widget實現者的責任。當widget能夠動態更改時,須要使用StatefulWidget。 例如, 經過鍵入表單或移動滑塊來更改widget的狀態. 或者, 它能夠隨時間變化 - 或者數據推送更新UI
Checkbox
, Radio
, Slider
, InkWell
, Form
, 和 TextField
都是有狀態的widget,也是StatefulWidget的子類。
下面的示例聲明瞭一個StatefulWidget,它須要一個createState()
方法。此方法建立管理widget狀態的狀態對象_MyStatefulWidgetState。
class MyStatefulWidget extends StatefulWidget {
MyStatefulWidget({Key key, this.title}) : super(key: key);
final String title;
@override
_MyStatefulWidgetState createState() => _MyStatefulWidgetState();
}
複製代碼
以上代碼片斷的完整部分能夠在課程源碼中查找。
如下狀態類_MyStatefulWidgetState實現widget的build()
方法。當狀態改變時,例如,當用戶切換按鈕時,使用新的切換值調用setState
。這會致使框架在UI中重建此widget。
class _MyStatefulWidgetState extends State<MyStatefulWidget> {
bool showtext=true;
bool toggleState=true;
Timer t2;
void toggleBlinkState(){
setState((){
toggleState=!toggleState;
});
var twenty = const Duration(milliseconds: 1000);
if(toggleState==false) {
t2 = Timer.periodic(twenty, (Timer t) {
toggleShowText();
});
} else {
t2.cancel();
}
}
void toggleShowText(){
setState((){
showtext=!showtext;
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Column(
children: <Widget>[
(showtext
?(Text('This execution will be done before you can blink.'))
:(Container())
),
Padding(
padding: EdgeInsets.only(top: 70.0),
child: RaisedButton(
onPressed: toggleBlinkState,
child: (toggleState
?( Text('Blink'))
:(Text('Stop Blinking'))
)
)
)
],
),
),
);
}
複製代碼
以上代碼片斷的完整部分能夠在課程源碼中查找。
在設計widget時,須要考慮如下幾點。
- 肯定widget應該使用StatefulWidget仍是StatelessWidget
在Flutter中,widget是有狀態的仍是無狀態的 - 取決因而否 他們依賴於狀態的變化
- 肯定哪一個對象管理widget的狀態(對於StatefulWidget) 在Flutter中,管理狀態有三種主要方式:
如何決定使用哪一種方式時,能夠參考如下原則:
- StatefulWidget 和 Stated的子類
MyStatefulWidget類管理本身的狀態 - 它擴展了StatefulWidget,它覆蓋createState()
方法來建立State對象,框架調用createState()
來構建widget。在這個例子中,createState()
建立了一個_MyStatefulWidgetState的實例 在下一個最佳實踐中實現:
class MyStatefulWidget extends StatefulWidget {
MyStatefulWidget({Key key, this.title}) : super(key: key);
final String title;
@override
_MyStatefulWidgetState createState() => _MyStatefulWidgetState();
}
class _MyStatefulWidgetState extends State<MyStatefulWidget> {
@override
Widget build(BuildContext context) {
...
}
}
複製代碼
以上代碼片斷的完整部分能夠在課程源碼中查找。
- 將StatefulWidget添加到widget樹中
將自定義的StatefulWidget添加到應用程序構建方法中的widget樹中:
class MyStatelessWidget extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyStatefulWidget(title: 'State Change Demo'),
);
}
}
複製代碼
以上代碼片斷的完整部分能夠在課程源碼中查找。