Flutter:界面刷新和生命週期

目錄傳送門:《Flutter快速上手指南》先導篇git

在 Flutter 中,有兩類經常使用的 Widget:github

  • 無狀態的 StatelessWidgetbash

  • 有狀態的 StatefulWidgetapp

在開發過程當中,咱們常常須要繼承它們兩來實現本身的 Widget。less

1. StatelessWidget

一個 StatelessWidget 是不能被改變的,好比:IconText等。ide

若是你的控件一旦顯示,就不須要再作任何的變動,那麼你應該使用 StatelessWidget函數

實現一個本身的 StatelessWidget 很簡單。post

當你看到下面這個例子🌰時,你就知道它有多簡單了。ui

class MyWidget extends StatelessWidget {

  @override
  Widget build(BuildContext context) {
    return _buildMyWidget(context);
  }
複製代碼

看,只要在 build() 中返回你的視圖就能夠了。spa

2. StatefulWidget

一個 StatefulWidget 是有狀態的,可變的。

它能夠改變本身的外觀,以響應用戶的操做或者數據的變化。

好比:CheckBoxSwitch..

咱們之因此可以改變一個 StatefulWidget,是由於它有一個設置狀態的函數:

setState((){
    // 更新狀態、數據
})
複製代碼

調用這個函數後,就會觸發 StatefulWidget 的視圖樹重建。

所以,當咱們須要一個可交互的,即能根據用戶操做或數據變化而改變視圖的 Widget 時,那就得用上 StatelessWidget 了。

2.1 自定義 StatefulWidget

如今,來建立一個自定義的 StatefulWidget:

  1. 實現一個 StatefulWidget,它是 Widget 的外層。

    class FavoriteStatefulWidget extends StatefulWidget {
    
      // 必須重寫 createState(),返回一個 State,它包含了視圖和交互邏輯
      @override
      State<StatefulWidget> createState() => _FavoriteStatefulWidgetState();
    }
    複製代碼
  2. 實現一個 State,它提供了真正的 Widget 視圖和交互邏輯。

    class _FavoriteStatefulWidgetState extends State<FavoriteStatefulWidget> {
      bool _isFavorited = true;
      int _favoriteCount = 41;
    
      void _toggleFavorite() {
        // 經過 setState() 更新數據
        // 組件樹就會自動刷新了
        setState(() {
          if (_isFavorited) {
            _favoriteCount -= 1;
            _isFavorited = false;
          } else {
            _favoriteCount += 1;
            _isFavorited = true;
          }
        });
      }
    
      // 重寫 build() 函數,構建視圖樹
      @override
      Widget build(BuildContext context) => Row(
            mainAxisSize: MainAxisSize.min,
            children: [
              Container(
                padding: EdgeInsets.all(0),
                child: IconButton(
                  icon: (_isFavorited ? Icon(Icons.star) : Icon(Icons.star_border)),
                  color: Colors.red[500],
                  onPressed: _toggleFavorite,
                ),
              ),
              SizedBox(
                width: 18,
                child: Container(
                  child: Text('$_favoriteCount'),
                ),
              ),
            ],
          );
    }
    複製代碼
  3. 使用這個自定義的 StatefulWidget 看看效果。

    main() => runApp(MaterialApp(
          title: 'Flutter Demo',
          home: Scaffold(
            appBar: AppBar(
              title: Text('Flutter Demo'),
            ),
            body: Container(
              color: Colors.white,
              child: Center(
                child: FavoriteStatefulWidget(),
              ),
            ),
          ),
        ));
    複製代碼

2.2 State 的生命週期

從上面的例子中能夠看到,StatefulWidget 會要求提供一個含有視圖樹的 State

既然 State 可以控制一個視圖的狀態,那它確定會有一系列的生命週期。

上圖就是 State 的生命週期圖。

  1. StatefulWidget.createState()

    Framework 調用會經過調用 StatefulWidget.createState() 來建立一個 State。

  2. initState()

    新建立的 State 會和一個 BuildContext 產生關聯,此時認爲 State 已經被安裝好了,initState() 函數將會被調用。

    一般,咱們能夠重寫這個函數,進行初始化操做。

  3. didChangeDependencies()

    initState() 調用結束後,這個函數會被調用。

    事實上,當 State 對象的依賴關係發生變化時,這個函數總會被 Framework 調用。

  4. build()

    通過以上步驟,系統認爲一個 State 已經準備好了,就會調用 build() 來構建視圖。

    咱們須要在這個函數中,返回一個 Widget。

  5. deactivate()

    當 State 被暫時從視圖樹中移除時,會調用這個函數。

    頁面切換時,也會調用它,由於此時 State 在視圖樹中的位置發生了變化,須要先暫時移除後添加。

    ⚠️注意,重寫的時候必需要調用 super.deactivate()

  6. dispose()

    當 State 被永久的從視圖樹中移除,Framework 會調用該函數。

    在銷燬前觸發,咱們能夠在這裏進行最終的資源釋放。

    在調用這個函數以前,總會先調用 deactivate()

    ⚠️注意,重寫的時候必需要調用 super.dispose()

  7. didUpdateWidget(covariant T oldWidget)

    當 widget 的配置發生變化時,會調用這個函數。

    好比,Hot-reload 的時候就會調用這個函數。

    這個函數調用後,會調用 build()

  8. setState()

    當我須要更新 State 的視圖時,須要手動調用這個函數,它會觸發 build()

目錄傳送門:《Flutter快速上手指南》先導篇

如何找到我?

傳送門:CoorChice 的主頁

傳送門:CoorChice 的 Github

相關文章
相關標籤/搜索