Flutter入門並開發天氣預報APP(3)——Widget

1. 簡介

在Flutter中,Widget是個非常基本的東西,我在上一章就說過,Flutter中只要是界面都是Widget,你可以把它就理解成是控件,但是又和Android的View控件不同的是,在Flutter中,包括PaddingAlign、手勢檢測的GestureDetector等等,都算是Widget

其實大多數時候,你就可以把Widget直接理解成UI控件就行了,因爲PaddingAlignGestureDetector等等也都是爲UI服務的,你就可以理解成Flutter中只要與UI有關的屬性都可以算是控件。

2. Widget的狀態

在Android中,我們可以直接通過更新數據來達到刷新UI的目的。但是如果使用Flutter,就像我們前面說的計數器的Demo,如果直接通過StatelessWidget也就是無狀態Widget的話,是沒法進行刷新UI的,只能寫一個死界面,也就是說如果在Flutter中界面寫出來的就是一個死界面,只有通過刷新狀態才能更新UI。

Widget有兩個直接子類:StatelessWidgetStatefulWidget

  • StatelessWidget:這個是無狀態Widget,實現build()方法後,就不可再變化,哪怕他的狀態改變了。這句話可能有點矛盾,但是我來舉個例子,比方說現在有一個StatelessWidget,他的內容就是一個Text,而這個Text的內容則顯示了counter這個變量。當這個頁面出現的時候,取了當時counter的值並顯示了出來,但是我們後續不管counter這個值怎麼改變,界面都是不會顯示出來的。
  • StatefulWidget:這個是有狀態Widget,當你有狀態需要改變的時候就可以通過他來改變狀態。

State的幾種狀態:

名稱 狀態
initState create之後被insert到渲染樹時調用的,只會調用一次
didChangeDependencies state依賴的對象發生變化時調用
didUpdateWidget Widget狀態改變時候調用,可能會調用多次
build 構建Widget時調用
deactivate 當移除渲染樹的時調用
dispose Widget即將銷燬時調用

3. StatelessWidget

這個類相對簡單,只需要實現build()方法就可以了。

StatelessWidget用於不需要維護狀態的場景,也就是說如果他需要顯示的某一個參數的值發生變化了他也不變。

class Test extends StatelessWidget {
  Test({Key key, this.title}) : super(key: key);

  final String title;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: new AppBar(
        title: Text("$title"),
      ),
      body: Text("1234"),
    );
  }
}

上面代碼就演示了一個StatelessWidget的例子,功能是根據傳入的title在界面的title了上顯示出來。只實現了build()方法和構造方法。其中構造方法參數Key是必須得有的,而且如果該Widget還有其他狀態的話,也需要寫入構造方法。接着調用build()方法,將傳入的title在界面的title上顯示出來。

例如,如果我們調用它:

@override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: Test(title: 'Flutter Demo Home Page'),
    );
  }

結果是:
在這裏插入圖片描述

4. StatefulWidget

StatelessWidget相對的就是StatefulWidget。它的重點在於可以根據狀態來更新。

他較於StatelessWidget,少了我們常用的build()方法,多了createState()方法。下面我就來講一下他的用法,我還是拿上面的Test做例子。

class Test extends StatefulWidget {
  Test({Key key, this.title}) : super(key: key);

  final String title;

  @override
  _TestState createState() => _TestState();
}

class _TestState extends State<Test> {
  String _title;

  @override
  void initState() {
    setState(() {
      _title = widget.title;
    });
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: new AppBar(
        title: Text("$_title"),
      ),
      body: Text("1234"),
    );
  }
}

先看Test類,他繼承自StatefulWidget,由於這個頁面需要根據傳入的參數來顯示title,所以有一個狀態title,並在構造方法中寫入了他。接着調用了createState()方法。這個方法是所有StatefulWidget必須的,主要是爲這個Widget創建他對應的State。

於是我們就在下面創建一個新的類,類名叫_TestState,繼承自State<Test>。由於Widget有title這個狀態,並且需要在界面中顯示出來,所以爲了降低他們的耦合度,我們在State類中也創建一個叫_title的狀態,並_title = widget.title;
接下來是一個initState()方法,這個方法也是State必須的,在上面Widget的狀態中我們講到過,這個是初始化State的,同時在initSate()裏面,我們寫了一個setState(),也就是說我們告訴Flutter說這個方法裏面的參數改變了接着Widget的狀態也得改變。最後就是build()方法。

接下來我們調用它:

@override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: Test(title: '1234'),
    );
  }

結果是:
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章