兩分鐘帶你掌握Flutter的StatelessWidget與StatefulWidget

爲你們傾力打造的課程《Flutter從入門到進階-實戰攜程網App》上線了,點我Get!!!html

在這篇文章中,將帶着你們一塊兒認識什麼是StatelessWidget?什麼是StatefulWidget?,以及StatefulWidget和StatelessWidget都有哪些最佳實踐?ios

狀態是在構建widget時能夠同步讀取的信息,或者在widget的生命週期中可能更改的信息,在Flutter中若是要管理狀態須要用到 StatefulWidgetapp

什麼是StatelessWidget?

Flutter中的StatelessWidget是一個不須要狀態更改的widget - 它沒有要管理的內部狀態。框架

當您描述的用戶界面部分不依賴於對象自己中的配置信息以及widget的BuildContext 時,無狀態widget很是有用。less

AboutDialog, CircleAvatarText 都是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方法一般只會在如下三種狀況調用:佈局

  • 將widget插入樹中時
  • 當widget的父級更改其配置時
  • 當它依賴的InheritedWidget發生變化時

什麼是StatefulWidget?

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'))
                )
              )
            )
          ],
        ),
      ),
    );
  }
複製代碼

以上代碼片斷的完整部分能夠在課程源碼中查找。

StatefulWidget和StatelessWidget有哪些最佳實踐?

在設計widget時,須要考慮如下幾點。

  1. 肯定widget應該使用StatefulWidget仍是StatelessWidget

在Flutter中,widget是有狀態的仍是無狀態的 - 取決因而否 他們依賴於狀態的變化

  • 若是用戶交互或數據改變致使widget改變,那麼它就是有狀態的。
  • 若是一個widget是最終的或不可變的,那麼它就是無狀態。
  1. 肯定哪一個對象管理widget的狀態(對於StatefulWidget) 在Flutter中,管理狀態有三種主要方式:
  • 每一個widget管理本身的狀態
  • 父widget管理widget的狀態
  • 混合搭配管理的方法

如何決定使用哪一種方式時,能夠參考如下原則:

  • 若是所討論的狀態是用戶數據,例如複選框的已選中或未選中狀態,或滑塊的位置,則狀態最好由父widget管理;
  • 若是widget的狀態取決於動做,例如動畫,那麼最好是由widget自身來管理狀態;
  • 若有仍是不肯定誰管理狀態,請讓父widget管理子widget的狀態;
  1. 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) {
    ...
  }
}
複製代碼

以上代碼片斷的完整部分能夠在課程源碼中查找。

  1. 將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'),
    );
  }
}
複製代碼

以上代碼片斷的完整部分能夠在課程源碼中查找。

state-change-ios
state-change-ios

未完待續

  • Flutter入門基礎知識
  • Flutter主題和文字處理
  • Flutter什麼是聲明式UI
  • Flutter佈局與列表
  • Flutter手勢檢測及觸摸事件處理
  • Flutter狀態管理d
  • Flutter線程和異步UI
  • Flutter表單輸入與富文本
  • Flutter認識視圖(Views)md
  • Flutter調用硬件、第三方服務以及平臺交互、通知
  • Flutter路由與導航
  • Flutter項目結構、資源、依賴和本地化

參考

相關文章
相關標籤/搜索