Flutter系列(3)Flutter中的Widget、State

Flutter 的設計思想是“一切皆 Widget”馋艺。

一栅干、demo解讀

我們新建一個Flutter項目,默認生成一個demo捐祠,代碼如下:

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

//1碱鳞、MyApp 是一個 StatelessWidget
class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

//2 、MyHomePage 是一個 StatefulWidget
class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);
  
  final String title;

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

//3踱蛀、 _MyHomePageState 是一個 State
class _MyHomePageState extends State<MyHomePage> {
  int _counter = 0;

  void _incrementCounter() {
    setState(() {
      _counter++;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(

        title: Text(widget.title),
      ),
      body: Center(

        child: Column(

          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text(
              'You have pushed the button this many times:',
            ),
            Text(
              '$_counter',
              style: Theme.of(context).textTheme.display1,
            ),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _incrementCounter,
        tooltip: 'Increment',
        child: Icon(Icons.add),
      ), 
    );
  }
}

除去控件部分不說窿给,我們的Flutter demo由 StatelessWidgetStatefulWidgetState 構(gòu)成。

StatelessWidget:處理靜態(tài)的星岗,無狀態(tài)的視圖展示填大。

StatefulWidget:應對有交互,需要動態(tài)變化視覺效果的場景俏橘,例如圖片控件。

通過父View初始化時傳入的靜態(tài)配置圈浇,StatelessWidget就能完全控制其靜態(tài)顯示寥掐。而StatefulWidget還要借助State對象,處理用戶交互和UI變化磷蜀,并體現(xiàn)在UI上召耘。

二、Widget 設計思路和基本原理

Widget褐隆、Element污它、RenderObject

界面
生成三棵樹

Widget是視圖結(jié)構(gòu)描述,Element是Widget的一個實例化對象庶弃,將Widget樹的變化做了抽象衫贬,能夠只將需要修改的部分同步到真正的RenderObject樹中。

三棵樹設計的好處是提高性能歇攻,RenderObject 的創(chuàng)建是比較耗性能的固惯,涉及到底層的繪制邏輯,而Widget樹每次刷新都會重建缴守,Element樹會跟上次繪制的Element對比看哪些是有變化的葬毫,只對有變化的對象創(chuàng)建對應的RenderObject。

二屡穗、組件

StatelessWidget 和 StatefulWidget

StatelessWidget:處理靜態(tài)的贴捡,無狀態(tài)的視圖展示。

StatefulWidget:應對有交互村砂,需要動態(tài)變化視覺效果的場景烂斋。

通過父View初始化時傳入的靜態(tài)配置,StatelessWidget就能完全控制其靜態(tài)顯示。而StatefulWidget還要借助State對象源祈,處理用戶交互和UI變化煎源,并體現(xiàn)在UI上。

State生命周期

State生命周期

1.創(chuàng)建

  • 構(gòu)造:可以接收父View傳遞的數(shù)據(jù)
  • initState:會在State插入視圖樹的時候調(diào)用香缺,生命周期只會調(diào)一次手销,可以為變量設置默認值。
  • didChangeDependencies:專門處理State對象依賴關(guān)系變化图张。
  • build:創(chuàng)建視圖锋拖,經(jīng)過以上步驟,F(xiàn)ramework認為State已經(jīng)準備好祸轮,調(diào)用build方法兽埃,創(chuàng)建一個Widget返回

2.更新

Widget狀態(tài)更新,主要由三個方法觸發(fā)适袜,setState柄错、didChangeDependencies、didUpdateWidget

  • setState:數(shù)據(jù)改變就通過這個方法告訴Flutter我這里數(shù)據(jù)改變苦酱,需要重建UI售貌,會調(diào)用build方法

  • didChangeDependencies:系統(tǒng)語言或主題改變時會回調(diào)。

  • didUpdateWidget:Widget配置關(guān)系發(fā)生變化疫萤,例如父View觸發(fā)重建颂跨,熱重載時會地哦啊用這個方法。

一旦以上方法被調(diào)用扯饶,F(xiàn)lutter會銷毀老的Widget恒削,調(diào)用build方法重建Widget。

3.銷毀

  • deactivate:組件的可見狀態(tài)發(fā)生變化會被調(diào)用尾序。頁面切換時钓丰,State對象在視圖樹中發(fā)生變化,需要暫時移除后重新添加蹲诀,會觸發(fā)組件重建斑粱,調(diào)用這個方法。
  • dispose:State被永久從視圖樹中移除時調(diào)用脯爪,組件就要銷毀了则北,可以做一些資源回收操作

4. App生命周期監(jiān)聽

WidgetsBindingObserver

官方demo

class AppLifecycleReactor extends StatefulWidget {
  const AppLifecycleReactor({ Key key }) : super(key: key);

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

class _AppLifecycleReactorState extends State<AppLifecycleReactor> with WidgetsBindingObserver {
  @override
  void initState() {
    super.initState();
    WidgetsBinding.instance.addObserver(this);
  }

  @override
  void dispose() {
    WidgetsBinding.instance.removeObserver(this);
    super.dispose();
  }

  AppLifecycleState _notification;

  @override
  void didChangeAppLifecycleState(AppLifecycleState state) {
    setState(() { _notification = state; });
  }

  @override
  Widget build(BuildContext context) {
    return Text('Last notification: $_notification');
  }
}

5.幀數(shù)據(jù)回調(diào)

    WidgetsBinding.instance.addPostFrameCallback((_){
      print("FrameCallback 單次Frameh繪制回調(diào)"); //只回調(diào)一次
    });

    WidgetsBinding.instance.addPersistentFrameCallback((_){
      print("FrameCallback 實時Frameh繪制回調(diào)"); //每一幀都回調(diào)
    });

觸發(fā)setState,就能看到日志痕慢。

參考:
極客時間-Flutter核心技術(shù)與實戰(zhàn)
《Flutter實戰(zhàn)》電子書-基礎組件

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末尚揣,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子掖举,更是在濱河造成了極大的恐慌快骗,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,311評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異方篮,居然都是意外死亡名秀,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,339評論 2 382
  • 文/潘曉璐 我一進店門藕溅,熙熙樓的掌柜王于貴愁眉苦臉地迎上來匕得,“玉大人,你說我怎么就攤上這事巾表≈樱” “怎么了?”我有些...
    開封第一講書人閱讀 152,671評論 0 342
  • 文/不壞的土叔 我叫張陵集币,是天一觀的道長考阱。 經(jīng)常有香客問我,道長鞠苟,這世上最難降的妖魔是什么乞榨? 我笑而不...
    開封第一講書人閱讀 55,252評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮当娱,結(jié)果婚禮上姜凄,老公的妹妹穿的比我還像新娘。我一直安慰自己趾访,他們只是感情好,可當我...
    茶點故事閱讀 64,253評論 5 371
  • 文/花漫 我一把揭開白布董虱。 她就那樣靜靜地躺著扼鞋,像睡著了一般。 火紅的嫁衣襯著肌膚如雪愤诱。 梳的紋絲不亂的頭發(fā)上云头,一...
    開封第一講書人閱讀 49,031評論 1 285
  • 那天,我揣著相機與錄音淫半,去河邊找鬼溃槐。 笑死,一個胖子當著我的面吹牛科吭,可吹牛的內(nèi)容都是我干的昏滴。 我是一名探鬼主播,決...
    沈念sama閱讀 38,340評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼对人,長吁一口氣:“原來是場噩夢啊……” “哼谣殊!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起牺弄,我...
    開封第一講書人閱讀 36,973評論 0 259
  • 序言:老撾萬榮一對情侶失蹤姻几,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體蛇捌,經(jīng)...
    沈念sama閱讀 43,466評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡抚恒,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,937評論 2 323
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了络拌。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片俭驮。...
    茶點故事閱讀 38,039評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖盒音,靈堂內(nèi)的尸體忽然破棺而出表鳍,到底是詐尸還是另有隱情,我是刑警寧澤祥诽,帶...
    沈念sama閱讀 33,701評論 4 323
  • 正文 年R本政府宣布譬圣,位于F島的核電站,受9級特大地震影響雄坪,放射性物質(zhì)發(fā)生泄漏厘熟。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,254評論 3 307
  • 文/蒙蒙 一维哈、第九天 我趴在偏房一處隱蔽的房頂上張望绳姨。 院中可真熱鬧,春花似錦阔挠、人聲如沸飘庄。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,259評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽跪削。三九已至,卻和暖如春迂求,著一層夾襖步出監(jiān)牢的瞬間碾盐,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評論 1 262
  • 我被黑心中介騙來泰國打工揩局, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留毫玖,地道東北人。 一個月前我還...
    沈念sama閱讀 45,497評論 2 354
  • 正文 我出身青樓凌盯,卻偏偏與公主長得像付枫,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子十气,可洞房花燭夜當晚...
    茶點故事閱讀 42,786評論 2 345

推薦閱讀更多精彩內(nèi)容