Flutter之HolleWold

Flutter 第一個(gè)項(xiàng)目是一個(gè)計(jì)數(shù)器

Flutter 的Dart代碼是寫在lib 文件夾下畴椰,而 lib/main.dart 是項(xiàng)目的入口,打開main.dart 掸绞,下邊是代碼:

//引入material UI庫,可以理解為iOS的UIKit
import 'package:flutter/material.dart';

// 傳說中的main 函數(shù),使用dart 的特有的  => 調(diào)用方法
// 調(diào)用了MyApp函數(shù)
void main() => runApp(new MyApp());

// Widget(部件)捍歪,可以理解為iOS中的UIView,iOS中叫控件鸵钝,都由view封裝而成糙臼,F(xiàn)lutter中都叫部件(小部件),都由widget封裝而成
// extends:繼承(OC不這么寫恩商,因?yàn)镺C 一個(gè)類有2個(gè)文件組成 .h和.m)--OC 是最NB的[偷笑]变逃!
class MyApp extends StatelessWidget {
  //重寫 build 方法(描述如何構(gòu)建UI界面)
  @override
  Widget build(BuildContext context) {
  // MaterialApp :是Material庫中提供的Flutter APP框架,通過它可以設(shè)置應(yīng)用的名稱怠堪、主題揽乱、語言、首頁及路由列表等
    return new MaterialApp(
 //名稱
      title: 'Flutter Demo',
//主題
      theme: new ThemeData(
        primarySwatch: Colors.blue,
      ),
//應(yīng)用首頁路由 
      home: new MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}
//首頁
class MyHomePage extends StatefulWidget {
//可選參數(shù)粟矿,首頁導(dǎo)航標(biāo)題凰棉,如果不清楚可以
  MyHomePage({Key key, this.title}) : super(key: key);
  final String title;
// 加載首頁的狀態(tài)類,StatefulWidget 的特殊寫法陌粹,下邊詳細(xì)介紹
  @override
  _MyHomePageState createState() => new _MyHomePageState();
}
// State 狀態(tài)
// <MyHomePage> 這這個(gè)類的狀態(tài)
class _MyHomePageState extends State<MyHomePage> {
//記錄計(jì)數(shù)器的數(shù)字
  int _counter = 0;
// 點(diǎn)擊 “+” 按鈕調(diào)用的方法撒犀,實(shí)現(xiàn) i++
// _incrementCounter 這種下劃線的命名的方法,表示是一個(gè)私有方法
  void _incrementCounter() {
// 刷新頁面
    setState(() {
      _counter++;
    });
  }

  @override
  Widget build(BuildContext context) {
// Scaffold :是Material庫中提供的頁面腳手架掏秩,它包含導(dǎo)航欄和Body以及FloatingActionButton
// 就是一個(gè)封裝了導(dǎo)航欄等等功能的小部件绘证,可以簡單理解為UINavgation
    return new Scaffold(
// 導(dǎo)航欄
      appBar: new AppBar(
        title: new Text(widget.title),
      ),
// Center : 一個(gè)空白的view (web 中的 div )
      body: new Center(
// Column: 一種布局方案,下一章布局詳細(xì)介紹 
        child: new Column(
// 布局中的對齊哗讥,居中
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
// lab
            new Text(
              'You have pushed the button this many times:',
            ),
            new Text(
              '$_counter',
              style: Theme.of(context).textTheme.display1,
            ),
          ],
        ),
      ),
// 按鈕
      floatingActionButton: new FloatingActionButton(
        onPressed: _incrementCounter,// 調(diào)用方法
        tooltip: 'Increment',
        child: new Icon(Icons.add),// icon
      ), // This trailing comma makes auto-formatting nicer for build methods.
    );
  }
}

代碼還是比較簡單的嚷那,點(diǎn)擊按鈕,調(diào)用 _incrementCounter 方法杆煞,_counter++魏宽,刷新頁面腐泻,讓 Text 顯示

接下來,詳細(xì)介紹一下队询,里邊包含的知識點(diǎn):

StatelessWidget 和 StatefulWidget

StatelessWidget: 無狀態(tài)Widget派桩,一旦創(chuàng)建,不能改變
StatefulWidget: 有狀態(tài)的Widget蚌斩,可以根據(jù)狀態(tài)改變

  1. StatefulWidget 其實(shí)就是 StatelessWidget + 狀態(tài)組成
  2. 其實(shí) StatefulWidget 能夠改變铆惑,也只是保存了“狀態(tài)”,刪除了老的StatelessWidget送膳,重新創(chuàng)建了一個(gè)新的
  3. 所以StatelessWidget 是一個(gè)方法员魏,而StatefulWidget 要多寫一個(gè) State 方法

刷新頁面 setState

// 下邊2種寫法都可以
_counter++;
setState(() {});

setState(() {
      _counter++;
});
  1. 調(diào)用刷新頁面,刪除了老的StatelessWidget叠聋,新建一個(gè)StatelessWidget撕阎,重新展示改變狀態(tài)以后的頁面
  2. 代碼邏輯其實(shí)重新執(zhí)行build 方法,來重繪碌补,所以build 方法里邊只放和頁面布局相關(guān)的東西虏束,不要放邏輯代碼

widget 底層

widget 繼承DiagnosticableTree,主要的包括key厦章,Element 镇匀,canUpdate等等。

  1. key:這個(gè)key屬性類似于React/Vue中的key袜啃,主要的作用是決定是否在下一次build時(shí)復(fù)用舊的widget汗侵,決定的條件在canUpdate()方法中。
  2. canUpdate:是否用新的Widget對象去更新舊UI樹上所對應(yīng)的Element對象的配置囊骤;只要newWidget與oldWidget的runtimeType和key同時(shí)相等時(shí)就會用newWidget去更新Element對象的配置晃择,否則就會創(chuàng)建新的Element。
  3. Element屬性

事實(shí)上 Widget 只是 Element 的一個(gè)配置描述 也物,告訴 Element 這個(gè)實(shí)例如何去渲染宫屠。
從上圖注釋也可知: Widget 和 Element 之間是一對多的關(guān)系 。

而Element 里邊有renderObject屬性

而renderObject 是Flutter布局和繪制的基本單元

由此可以得出: Widget 生成了 Element滑蚯,而后創(chuàng)建 RenderObject 關(guān)聯(lián)到 Element 的內(nèi)部 renderObject 對象上浪蹂,最后Flutter 通過 RenderObject 數(shù)據(jù)來布局和繪制。

說到 RenderObject 告材,就不得不說 RenderBox 坤次,從源碼注釋可以看出,它是在繼承 RenderObject 基礎(chǔ)的布局和繪制功能上斥赋,實(shí)現(xiàn)了“笛卡爾坐標(biāo)系”:以 Top缰猴、Left 為基點(diǎn),通過寬高兩個(gè)軸實(shí)現(xiàn)布局和嵌套的疤剑。

RenderBox 避免了直接使用 RenderObject 的麻煩場景滑绒,其中 RenderBox 的布局和計(jì)算大小是在 performLayout() 和 performResize() 這兩個(gè)方法中去處理闷堡,很多時(shí)候我們更多的是選擇繼承 RenderBox 去實(shí)現(xiàn)自定義。

綜合上述情況疑故,我們知道:

  1. Widget只是顯示的數(shù)據(jù)配置杠览,所以相對而言是輕量級的存在,而 Flutter 中對 Widget 的也做了一定的優(yōu)化纵势,所以每次改變狀態(tài)導(dǎo)致的 Widget 重構(gòu)并不會有太大的問題踱阿。
  2. RenderObject 就不同了,RenderObject 涉及到布局钦铁、計(jì)算软舌、繪制等流程,要是每次都全部重新創(chuàng)建開銷就比較大了育瓜。

所以針對是否每次都需要?jiǎng)?chuàng)建出新的 Element 和 RenderObject 對象葫隙,Widget 都做了對應(yīng)的判斷以便于復(fù)用栽烂,比如:在 newWidget 與oldWidget 的 runtimeType 和 key 相等時(shí)會選擇使用 newWidget 去更新已經(jīng)存在的 Element 對象躏仇,不然就選擇重新創(chuàng)建新的 Element。

由此可知:Widget 重新創(chuàng)建腺办,Element 樹和 RenderObject 樹并不會完全重新創(chuàng)建焰手。

那么再來個(gè)圖理解一下:

widget 底層這塊參考大神所寫:
https://juejin.im/post/5c7e853151882549664b0543

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市怀喉,隨后出現(xiàn)的幾起案子书妻,更是在濱河造成了極大的恐慌,老刑警劉巖躬拢,帶你破解...
    沈念sama閱讀 219,110評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件躲履,死亡現(xiàn)場離奇詭異,居然都是意外死亡聊闯,警方通過查閱死者的電腦和手機(jī)工猜,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,443評論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來菱蔬,“玉大人篷帅,你說我怎么就攤上這事∷┟冢” “怎么了魏身?”我有些...
    開封第一講書人閱讀 165,474評論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長蚪腐。 經(jīng)常有香客問我箭昵,道長,這世上最難降的妖魔是什么回季? 我笑而不...
    開封第一講書人閱讀 58,881評論 1 295
  • 正文 為了忘掉前任家制,我火速辦了婚禮掉房,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘慰丛。我一直安慰自己卓囚,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,902評論 6 392
  • 文/花漫 我一把揭開白布诅病。 她就那樣靜靜地躺著哪亿,像睡著了一般。 火紅的嫁衣襯著肌膚如雪贤笆。 梳的紋絲不亂的頭發(fā)上蝇棉,一...
    開封第一講書人閱讀 51,698評論 1 305
  • 那天,我揣著相機(jī)與錄音芥永,去河邊找鬼篡殷。 笑死,一個(gè)胖子當(dāng)著我的面吹牛埋涧,可吹牛的內(nèi)容都是我干的板辽。 我是一名探鬼主播,決...
    沈念sama閱讀 40,418評論 3 419
  • 文/蒼蘭香墨 我猛地睜開眼棘催,長吁一口氣:“原來是場噩夢啊……” “哼劲弦!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起醇坝,我...
    開封第一講書人閱讀 39,332評論 0 276
  • 序言:老撾萬榮一對情侶失蹤邑跪,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后呼猪,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體画畅,經(jīng)...
    沈念sama閱讀 45,796評論 1 316
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,968評論 3 337
  • 正文 我和宋清朗相戀三年宋距,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了轴踱。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,110評論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡乡革,死狀恐怖寇僧,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情沸版,我是刑警寧澤嘁傀,帶...
    沈念sama閱讀 35,792評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站视粮,受9級特大地震影響细办,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,455評論 3 331
  • 文/蒙蒙 一笑撞、第九天 我趴在偏房一處隱蔽的房頂上張望岛啸。 院中可真熱鬧,春花似錦茴肥、人聲如沸坚踩。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,003評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽瞬铸。三九已至,卻和暖如春础锐,著一層夾襖步出監(jiān)牢的瞬間嗓节,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,130評論 1 272
  • 我被黑心中介騙來泰國打工皆警, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留拦宣,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,348評論 3 373
  • 正文 我出身青樓信姓,卻偏偏與公主長得像鸵隧,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子财破,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,047評論 2 355