Widget 概念前端
首先咱們須要瞭解下 widget 的概念,google 翻譯過來叫小部件。將 widget 想象爲一個可視化組件或與應用可視化方面交互的組件,同 view 可視化控件不一樣的是,widget 不是一個控件,而是對控件的描述,其實咱們也沒必要非要糾結概念這個東西,當你用的多了,也就領悟這個概念了。app
在 flutter 中,全部的東西都是 widget ,下面代碼中能夠看到 Text 、AppBar、 AppDemo、Scaffold 都是widget 。less
class AppDemo extends StatelessWidget { @override Widget build(BuildContext context) { return new Scaffold( appBar: new AppBar( title: new Text('flutter'), ), body: new Center( child:new Text('content'), ), ); } }
flutter 的核心思想就是用 widget 構建你的 UI 。而且它提供了一套豐富、強大的基礎 widget ,可參考 :https://flutterchina.club/wid...ide
Widget 狀態函數
在 flutter 中,widget 是不可變的,你須要去操縱 widget 的 state。widget 有狀態跟無狀態的區分。ui
無狀態 StatelessWidgetthis
StatelessWidget ( 無狀態的 widget ) 在你構建初始化後再也不進行改變。google
例如上面例子,代碼中的 child: new Text('content')
這個內容 content 不會變。那麼咱們就能夠用 StatelessWidget 的 Text 。假如咱們點擊按鈕後但願內容改變,咱們就須要瞭解下有狀態的 widget 。翻譯
有狀態 StatefulWidgetdebug
StatefulWidget ( 有狀態的 widget ) 擁有一個 state 對象來存儲它的狀態數據,並在 widget 樹重建時攜帶着它,所以狀態不會丟失。一個 StatefulWidget 類對應一個 state 類,state 是與對應 StatefulWidget 維護的狀態,
當 state 被改變時,調用 setState()
方法通知 flutter framework 狀態發生改變,從新調用 build
方法構建 widget 樹,來進行更新操做,看下面實例。
class AppDemo extends StatefulWidget { @override createState() => _AppDemoState(); } class _AppDemoState extends State<AppDemo> { String _content = "content"; void _updateContent() { setState((){ _content = "flutter content"; }); } @override Widget build(BuildContext context) { return new Scaffold( appBar: new AppBar( title: TextPage(title: 'flutter',), ), body: new Center( child:new Text(_content), ), floatingActionButton: FloatingActionButton( onPressed: _updateContent, child: Icon(Icons.mode_edit), ), ); } }
當點擊按鈕後,顯示的內容就會更改成 flutter content
Widget 生命週期
對於一個前端開發,咱們都比較關心生命週期這個話題,一樣理解 Widget 生命週期對 flutter 開發也是這樣的,例子:經過一個計數器 widget 的例子來理解這個話題。
class CounterWidget extends StatefulWidget { CounterWidget({this.initCounter:0}); final int initCounter; @override createState() => _CounterWidgetState(); } class _CounterWidgetState extends State<CounterWidget> { int _counter; @override void initState() { super.initState(); _counter = widget.initCounter; print('***************initState $_counter***************'); } @override Widget build(BuildContext context) { print('***************build***************'); return Center( child: RaisedButton( child: Text('$_counter'), onPressed: ()=>setState(()=>++_counter), ), ); } @override void didUpdateWidget(CounterWidget oldWidget) { super.didUpdateWidget(oldWidget); print('***************didUpdateWidget***************'); } @override void deactivate() { super.deactivate(); print("***************deactive***************"); } @override void dispose() { super.dispose(); print("***************dispose***************"); } @override void reassemble() { super.reassemble(); print("***************reassemble***************"); } @override void didChangeDependencies() { super.didChangeDependencies(); print("***************didChangeDependencies***************"); } }
經過現象得結論:
debug 啓動運行結果:
***************initState 0*************** ***************didChangeDependencies*************** ***************build***************
initState
:該 widiget 插入到 widget 樹結構時被調用,只調用一次,所以,該函數通常用來初始化操做,狀態初始化、訂閱子樹事件通知。
didChangeDependencies()
:當調用 initState
後會當即調用這個方法,這個方法是在 state 對象被建立好了但沒有準備好構建 build
的時候調用的。
build
: 調用這個方法來構建 widget 子樹。觸發的時機較多如:調用 initState()
、didChangeDependencies()
、setState()
、didUpdateWidget()
等方法後從新 build。
點擊保存按鈕執行結果:
***************reassemble*************** ***************didUpdateWidget*************** ***************build***************
reassemble()
:專門爲了開發調試而提供的,在熱重載時會被調用。
didUpdateWidget()
:在 widget 從新構建時,由 flutter framework 判斷檢測 widget 樹種同一位置新舊節點,決定是否更新,調用該方法。
移除 CounterWidget 執行結果:
***************reassemble*************** ***************deactive*************** ***************dispose***************
deactive
:當widget 對象從樹中被移除時,會調用此方法。
dispose
:當 widget 對象從樹中被永久移除時調用 ,能夠在此方法中釋放資源。
點擊按鈕執行結果:
***************build***************