最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網 會員登陸 & 注冊

Flutter快學快用24講--05 代碼規(guī)范:實踐開發(fā) Flutter 編程代碼規(guī)范工具

2023-03-15 21:53 作者:gzqhero  | 我要投稿

本課時將介紹 Flutter 的組件,以及組件的生命周期,其次結合上課時的例子實現(xiàn)一個自動更新展示最新時間的 Flutter 應用。

組件 Widget

Flutter 中的組件與前端組件的理解和作用基本一致,但是沒有一個明確的概念解釋 Flutter 組件,這里我借用前端的組件定義來解釋 Flutter 組件的概念。

一個 Flutter 組件,包含了組件的模板、樣式和交互等內容,外部只要按照組件設定的屬性、函數(shù)及事件處理等進行調用即可,完全不用考慮組件的內部實現(xiàn)邏輯。其中組件又包括無狀態(tài)組件和有狀態(tài)組件。

  • 無狀態(tài)組件

無狀態(tài)組件,可以理解為將外部傳入的數(shù)據(jù)轉化為界面展示的內容,只會渲染一次。

  • 有狀態(tài)組件

有狀態(tài)組件,是定義交互邏輯和業(yè)務數(shù)據(jù),可以理解為具有動態(tài)可交互的內容界面,會根據(jù)數(shù)據(jù)的變化進行多次渲染。

生命周期

在原生 Android 、原生 iOS 、前端 React 或者 Vue 都存在生命周期的概念,在 Flutter 中一樣存在生命周期的概念,其基本概念和作用相似。 Flutter 中說的生命周期,也是指有狀態(tài)組件,對于無狀態(tài)組件生命周期只有 build 這個過程,也只會渲染一次,而有狀態(tài)組件則比較復雜,下面我們就來看看有狀態(tài)組件的生命周期過程。

生命周期的流轉

Flutter 中的生命周期,包含以下幾個階段:

  • createState ,該函數(shù)為 StatefulWidget 中創(chuàng)建 State 的方法,當 StatefulWidget 被調用時會立即執(zhí)行 createState 。

  • initState ,該函數(shù)為 State 初始化調用,因此可以在此期間執(zhí)行 State 各變量的初始賦值,同時也可以在此期間與服務端交互,獲取服務端數(shù)據(jù)后調用 setState 來設置 State。

  • didChangeDependencies ,該函數(shù)是在該組件依賴的 State 發(fā)生變化時,這里說的 State 為全局 State ,例如語言或者主題等,類似于前端 Redux 存儲的 State 。

  • build ,主要是返回需要渲染的 Widget ,由于 build 會被調用多次,因此在該函數(shù)中只能做返回 Widget 相關邏輯,避免因為執(zhí)行多次導致狀態(tài)異常。

  • reassemble ,主要是提供開發(fā)階段使用,在 debug 模式下,每次熱重載都會調用該函數(shù),因此在 debug 階段可以在此期間增加一些 debug 代碼,來檢查代碼問題。

  • didUpdateWidget ,該函數(shù)主要是在組件重新構建,比如說熱重載,父組件發(fā)生 build 的情況下,子組件該方法才會被調用,其次該方法調用之后一定會再調用本組件中的 build 方法。

  • deactivate ,在組件被移除節(jié)點后會被調用,如果該組件被移除節(jié)點,然后未被插入到其他節(jié)點時,則會繼續(xù)調用 dispose 永久移除。

  • dispose ,永久移除組件,并釋放組件資源。


image (7).png

圖 1 生命周期流程圖

整個過程分為四個階段:

  1. 初始化階段,包括兩個生命周期函數(shù) createState 和 initState;

  2. 組件創(chuàng)建階段,也可以稱組件出生階段,包括 didChangeDependencies 和 build;

  3. 觸發(fā)組件多次 build ,這個階段有可能是因為 didChangeDependencies、setState 或者 didUpdateWidget 而引發(fā)的組件重新 build ,在組件運行過程中會多次被觸發(fā),這也是優(yōu)化過程中需要著重需要注意的點;

  4. 最后是組件銷毀階段,deactivate 和 dispose。

組件首次加載執(zhí)行過程

我們先實現(xiàn)一段代碼,來看下組件在首次創(chuàng)建的執(zhí)行過程是否是按照圖 1 的流程。

1、 在 lib 中 pages 下創(chuàng)建 test_stateful_widget.dart ;

2、 在 test_stateful_widget.dart 添加如下代碼:

上述代碼把有狀態(tài)組件的一些生命周期函數(shù)都進行了重寫,并且在執(zhí)行中都打印了一些字符串標識,目的是可以看到該函數(shù)被執(zhí)行。

3、 然后在 main.dart 中加載該組件,代碼如下:

代碼修改后,我們打開手機模擬器,然后運行該 App ,在輸出控制臺可以看到下面的運行打印日志信息。

運行結果中,打印過程可以看到是按照我們上面圖 1 的執(zhí)行流程在運行的, 但其中最值得關注的是 build 運行了兩次。這是在開發(fā)模式下才會執(zhí)行的過程,在正式環(huán)境是不會出現(xiàn)的,因為重新渲染成本非常大,這個問題可以使用打印 build 的調用堆棧即可發(fā)現(xiàn)。如果你要關閉兩次 build 也可以實現(xiàn),在 Flutter 框架中搜索 constants.dart 文件,并找到下面這行代碼,將 defaultValue 從 false 修改為 true。

其實這里會 觸發(fā) didUpdateWidget 函數(shù),是因為 TestStatefulWidget 組件是 MyApp 組件中的子組件,從而導致 MyApp 函數(shù)中的 build 觸發(fā)子組件 didUpdateWidget 函數(shù)的執(zhí)行,具體會在下面觸發(fā)組件再次 build 中詳細說明。

觸發(fā)組件再次 build

觸發(fā)組件再次 build 有三種方式,一個是 setState ,另一個是 didChangeDependencies ,再一個是 didUpdateWidget 。

setState 比較容易理解,在數(shù)據(jù)狀態(tài)進行變化時,觸發(fā)組件 build ,在上面的代碼運行后的界面中,點擊中間的頁面提示如圖 2 位置,就可以看到在調用 setState 后,會調用 build 一個方法。


image (8).png

圖 2 測試組件運行界面

didChangeDependencies ,你可以理解為本組件依賴的全局 state 的值發(fā)生了變化,例如前端的 redux 中的數(shù)據(jù)發(fā)生了變化,也會進行 build 操作。一般情況下我們會將一些比較基礎的數(shù)據(jù)放到全局變量中,例如主題顏色、地區(qū)語言或者其他通用變量等。如果這些全局 state 發(fā)生狀態(tài)變化則會觸發(fā)該函數(shù),而該函數(shù)之后就會觸發(fā) build 操作。

didUpdateWidget 觸發(fā) build 我們需要從代碼層面來講解下,現(xiàn)在我們需要設計兩個組件,一個是我們剛實現(xiàn)的 TestStatefulWidget ,另外一個則是該組件的子組件,我們命名為SubStatefulWidget 。接下來我們在 TestStatefulWidget 加載該組件,在頭部 import 該組件,然后將 build 中的代碼修改為下面:

接下來我們實現(xiàn) SubStatefulWidget 子組件的代碼,和父組件基本相似,只是在打印處都加了 sub ,其次 build 實現(xiàn)邏輯也修改了,具體代碼如下:

代碼實現(xiàn)完成后,我們再重新加載 App ,可以看到如下運行日志信息。

  • 加載 TestStatefulWidget 組件,四個狀態(tài)函數(shù) createState、initState、didChangeDependencies 和 build;

  • 加載 SubStatefulWidget 組件,四個狀態(tài)函數(shù) createState、initState、didChangeDependencies 和 build;

  • TestStatefulWidget 進行二次 build ,因為父組件需要重新 build 觸發(fā)子組件的 didUpdateWidget ,didUpdateWidget 則觸發(fā) build。

為了驗證上面邏輯,我們現(xiàn)在再次點擊圖 3 中的紅色部分,來觸發(fā) TestStatefulWidget 組件的 build ,看下是否會觸發(fā)子組件的 didUpdateWidget 和 build。


image (9).png

圖 3 增加子組件界面點擊指示圖

在運行日志窗口可以看到增加了下面的日志信息。

這就說明了父組件的變化會引發(fā)子組件的 build ,雖然子組件沒有任何的改動。這點如果是在前端的話,是需要使用 shouldUpdateComponent ,來介紹重新構建,不過在 Flutter 中是沒有該功能來減少重新 build 的。

組件銷毀觸發(fā)

在上面的代碼基礎上,我們直接在 TestStatefulWidget 組件中注釋子組件 SubStatefulWidget 的調用,然后 熱重載 即可看到下面的日志信息(請注意一定是需要熱重載才會有效果,主要目的是一開始加載了該組件,后面再去掉該組件觸發(fā))。

綜合實踐

上一課時,只是簡單地顯示了一個時間,這里需要動態(tài)地顯示當前的時間?;谖覀儽菊n時的學習,我們需要實現(xiàn)以下幾點:

  1. 使用有狀態(tài)組件來實現(xiàn),需要創(chuàng)建兩個類 StatefulWidget 和 State ,分別為 HomePage 和 HomePageState 對應到一個文件 home_page.dart ;

  2. 定義一個當前時間的 state currentTimeStr ,定義一個獲取當前時間的函數(shù) getCurrentTime ,并在 initState 中調用一次該函數(shù)當前時間;

  3. 實現(xiàn)函數(shù) getCurrentTime 獲取當前時間;

  4. 定義并實現(xiàn)一個定時刷新的函數(shù) refreshTimeStr ,在定時函數(shù)中使用 Timer 定時使用 setState 來更新 state,并在 initState 中執(zhí)行該函數(shù);

  5. build 中展示當前時間的 state 值,以及一個前綴信息;

接下來我們按照上面的步驟來實現(xiàn)代碼。

步驟一:創(chuàng)建有狀態(tài)類

使用有狀態(tài)組件來實現(xiàn),在 lib 的 pages 目錄下創(chuàng)建 home_page.dart ,接下來在文件中創(chuàng)建兩個類 StatefulWidget 和 State ,分別為 HomePage 和 HomePageState,代碼如下。

步驟二:增加狀態(tài)變量,實現(xiàn)初始化

定義一個當前時間的 state currentTimeStr ,定義一個獲取當前時間的函數(shù) getCurrentTime ,并在 initState 中調用一次該函數(shù)當前時間,代碼如下。

步驟三:實現(xiàn) getCurrentTime 方法

實現(xiàn)函數(shù) getCurrentTime 獲取當前時間,代碼如下。

步驟四:定時 Timer 實現(xiàn) state 定時更新

定義并實現(xiàn)一個定時刷新的函數(shù) refreshTimeStr ,在定時函數(shù)中使用 Timer 定時使用 setState 來更新 state,并在 initState 中執(zhí)行該函數(shù) ,代碼如下。

步驟五:build 中顯示組件內容

build 中展示當前時間的 state 值,以及一個前綴信息。由于前綴是一個無狀態(tài)變量,因此我們盡量將該變量放在 StatefulWidget 類中。這里在 build 中使用了一個新的布局組件 Column ,目前你暫時可以不關注這個組件,只需要了解其是布局組件即可,代碼如下。

步驟六:main.dart 中加載 HomPage 組件

最后我們需要在 main.dart 中應用該組件,代碼如下。

步驟七:代碼美化和規(guī)范檢查,并運行程序

現(xiàn)在我們將代碼實現(xiàn)完成了,需要使用我們 04 課時的知識來進行美化代碼和檢查代碼是否規(guī)范,我們可以將美化和代碼規(guī)范檢查的兩個命令寫出一個 shell 腳本,每次只需要運行這個 shell 腳本( format_check.sh )檢查即可,代碼如下。

接下來,每次運行前執(zhí)行該腳本檢查。

檢查后,如果有問題則修復,沒有問題,再選擇手機模擬器運行該項目,既可以看到如下圖 2 動態(tài)效果了。


20200610_140500-2.gif

圖 2 增加動態(tài)時間顯示

總結

本課時主要介紹了組件中的有狀態(tài)組件和無狀態(tài)組件,關于有狀態(tài)組件則介紹了其各個生命周期函數(shù)的執(zhí)行場景以及實際觸發(fā)的應用場景。最后再通過有狀態(tài)組件優(yōu)化我們之前的時間展示的小功能。學完本課時后,你需要掌握如何實現(xiàn)有狀態(tài)組件,并了解有狀態(tài)組件中各個生命周期函數(shù)被觸發(fā)的時機。

以上就是本課時的主要內容,下一課時介紹有狀態(tài)組件和無狀態(tài)組件應用場景,以及如何區(qū)分使用有狀態(tài)組件和無狀態(tài)組件。

點擊此鏈接查看本課時源碼: https://github.com/love-flutter/flutter-column

Flutter快學快用24講--05 代碼規(guī)范:實踐開發(fā) Flutter 編程代碼規(guī)范工具的評論 (共 條)

分享到微博請遵守國家法律
宜兴市| 名山县| 兴和县| 托克托县| 阿尔山市| 盐边县| 隆子县| 柯坪县| 囊谦县| 横山县| 左贡县| 兴文县| 渑池县| 东乌珠穆沁旗| 准格尔旗| 南澳县| 福安市| 饶平县| 丰城市| 濮阳县| 界首市| 婺源县| 柳州市| 仪征市| 重庆市| 新乡县| 阳城县| 邢台市| 溧水县| 来凤县| 壶关县| 孟连| 无棣县| 偏关县| 固阳县| 稷山县| 龙胜| 衢州市| 恭城| 顺昌县| 安国市|