主頁 > 移動端開發 > Flutter狀態管理新的實踐

Flutter狀態管理新的實踐

2023-06-21 08:53:40 移動端開發

1 背景介紹

1.1 宣告式ui

宣告式UI其實并不是近幾年的新技術,但是近幾年宣告式UI框架非常的火熱,單說移動端,跨平臺方案有:RN、Flutter,iOS原生有:SwiftUI,android原生有:compose,可以看到宣告式UI是以后的前端發展趨勢,而狀態管理是宣告式UI框架的重要組成部分,

1.2 宣告式UI框架的狀態

在移動端之前的命令式UI框架,沒有狀態的概念,每個控制元件其實都是無狀態的,我們要更新UI需要手動的去set,命令式UI引入狀態的概念,狀態可以理解為訂閱了控制元件所依賴資料的變化,當一個控制元件依賴的資料發生變化時,自動重繪UI展示,最大的優勢就是可以很方便的做到UI和邏輯的解耦,

2 provider狀態管理

2.1 使用方式

定義一個頁面如下:

實作功能,當點擊“按鈕”的時候,更新“你好”這個組件
頁面部分代碼實作(基于StatelessWidget實作):

model部分實作:

2.2 問題和不足

點擊“按鈕”的時候查看頁面重繪,發現下表羅列的Widget都執行了重繪操作,使用Selector雖然被包裹的內容沒有重繪,但是需要進行校驗操作,

2.2.1 控制元件重繪

2.2.2 問題分析

  1. 使用不太靈活,想要消費事件重繪UI必須有頂層的Provider提供model,在一些復雜場景可能會增加邏輯復雜度
  2. 狀態重繪,不能實作最小粒度的管理
  3. 代碼不夠簡潔

3 新的狀態管理方式實踐

3.1 使用方式

實作同樣的上述頁面邏輯,代碼如下(同樣基于StatelessWidget實作):
首先不需要依賴外部的provider提供Model,任何想要獨立重繪的區域使用TosObWidget控制元件包裹即可,使用比較靈活,我們可以把TosObWidget插入到任何我們想要的位置(包括provider內),代碼邏輯比較簡潔

model實作:

model的實作更加簡潔,不需要繼承ChangeNotifier,所以可以把狀態資料定義在任何我們想要的地方,使用.tos擴展屬性回傳一個包含默認值的RxObj物件,當我們使用set方法更改RxObj的value的時候,通知依賴此物件的TosObWidget區域進行重繪,例:我們點擊按鈕的時候,_model.textA.value = https://www.cnblogs.com/Jcloud/archive/2023/06/20/“你好${_model.i++}”,執行后就會重繪依賴textA的TosObWidget(() => Text(_model.textA.value))區域

查看重繪狀態(與provider對比):

對比發現TosObWidget這種方式,只有依賴的資料發生變化的TosObWidget才會更新狀態,可以實作狀態重繪粒度最小化,提高性能

3.2 設計思路

3.2.1 TosObWidget

首先是使用入口,定義一個TosObWidget控制元件,入參為build函式,回傳widget,每個TosObWidget就是一個可獨立進行狀態重繪的區域

TosObWidget控制元件的實作如下:

TosObWidget的build函式為多載的其父類_ObzWidget的build函式,最侄訓被_ObzWidget的_ObzState呼叫,_ObzWidget的實作如下:

接下來查看_ObzState的實作,主要邏輯都在這個類進行實作,這里貼出所有的代碼(注意框起來的邏輯):

3.2.2 TosObWidget邏輯分析

  1. 首先_ObzState依賴一個RxObserver _observer變數
  2. RxObserver _observer這個 變數持有了_updateUI()這個方法,最侄訓通過這個方法重繪TosOBWidget的狀態
  3. 當TosObWidget執行build的時候,會通過一個靜態變數RxObserver.proxy把_observer共享出去
  4. 這樣TosObWidget包裹的內容,使用RxObj的getValue的時候會拿到被共享的_observer,這時建立RxObj和TosObWidget的聯系
  5. 聯系建立后,重置共享變數RxObserver.proxy
  6. 這樣在RxObj的value執行set方法時,會呼叫到與其系結的TosObWidget的_updateUI()這個函式

3.2.3 RxObj的實作

如下貼出RxObj的value的get和set函式:

  1. 當執行RxObj的value的get方法時,代碼如下,拿到 RxObserver的靜態成員變數proxy,型別為RxObserver(即為上一步TosObWidget共享出來的_observer)
  2. 判斷RxObserver.proxy不為空,且沒有被添加到_observers串列( List _observers),則添加
  3. 當執行RxObj的value的set方法時,校驗value是否與當前的value值相同,且判斷是否是首次創建(首次創建不會執行狀態重繪)
  4. 校驗完成后則賦值執行refresh()函式,更新TosObWidget的狀態

refresh()函式的實作如下:
observer.update()函式即為執行與Rxobj關聯的TosObWidget的_updateUI()函式:

看下RxObserver的實作:
注意框起來的邏輯,update函式即上面_ObzState的_updateUI()函式的參考

至此整個實作流程已經貫通了,接下來看下如何使用:

1)通過.tos擴展屬性定義RxObj變數:

2).tos擴展屬性的實作如下:

3)如果要創建一個默認值為空的,RxObj實體,使用如下方式:

此時如果我們使用RxObj的setValue方法,就會重繪依賴它的所有TosObWidget控制元件,如果有些情況下,沒有呼叫setValue方法,但是需要重繪狀態,可手動呼叫refresh()方法,實作如下:

至此,就完成了TosObWidget控制元件的狀態重繪

4 總結

注:基于本文示例的功能邏輯進行對比

作者:京東物流 張俊飛

來源:京東云開發者社區

轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/555731.html

標籤:其他

上一篇:Android Studio中SQLite的使用,主要介紹sqlite插入和讀出圖片(ViewBinder)的操作方法

下一篇:返回列表

標籤雲
其他(161423) Python(38243) JavaScript(25511) Java(18250) C(15238) 區塊鏈(8271) C#(7972) AI(7469) 爪哇(7425) MySQL(7260) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5875) 数组(5741) R(5409) Linux(5347) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4606) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2436) ASP.NET(2404) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) .NET技术(1984) HtmlCss(1970) 功能(1967) Web開發(1951) C++(1942) python-3.x(1918) 弹簧靴(1913) xml(1889) PostgreSQL(1881) .NETCore(1863) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 【從零開始擼一個App】Dagger2

    Dagger2是一個IOC框架,一般用于Android平臺,第一次接觸的朋友,一定會被搞得暈頭轉向。它延續了Java平臺Spring框架代碼碎片化,注解滿天飛的傳統。嘗試將各處代碼片段串聯起來,理清思緒,真不是件容易的事。更不用說還有各版本細微的差別。 與Spring不同的是,Spring是通過反射 ......

    uj5u.com 2020-09-10 06:57:59 more
  • Flutter Weekly Issue 66

    新聞 Flutter 季度調研結果分享 教程 Flutter+FaaS一體化任務編排的思考與設計 詳解Dart中如何通過注解生成代碼 GitHub 用對了嗎?Flutter 團隊分享如何管理大型開源專案 插件 flutter-bubble-tab-indicator A Flutter librar ......

    uj5u.com 2020-09-10 06:58:52 more
  • Proguard 常用規則

    介紹 Proguard 入口,如何查看輸出,如何使用 keep 設定入口以及使用實體,如何配置壓縮,混淆,校驗等規則。

    ......

    uj5u.com 2020-09-10 06:59:00 more
  • Android 開發技術周報 Issue#292

    新聞 Android即將獲得類AirDrop功能:可向附近設備快速分享檔案 谷歌為安卓檔案管理應用引入可安全隱藏資料的Safe Folder功能 Android TV新主界面將顯示電影、電視節目和應用推薦內容 泄露的Android檔案暗示了傳說中的谷歌Pixel 5a與折疊屏新機 谷歌發布Andro ......

    uj5u.com 2020-09-10 07:00:37 more
  • AutoFitTextureView Error inflating class

    報錯: Binary XML file line #0: Binary XML file line #0: Error inflating class xxx.AutoFitTextureView 解決: <com.example.testy2.AutoFitTextureView android: ......

    uj5u.com 2020-09-10 07:00:41 more
  • 根據Uri,Cursor沒有獲取到對應的屬性

    Android: 背景:呼叫攝像頭,拍攝視頻,指定保存的地址,但是回傳的Cursor檔案,只有名稱和大小的屬性,沒有其他諸如時長,連ID屬性都沒有 使用 cursor.getInt(cursor.getColumnIndexOrThrow(MediaStore.Video.Media.DURATIO ......

    uj5u.com 2020-09-10 07:00:44 more
  • Android連載29-持久化技術

    一、持久化技術 我們平時所使用的APP產生的資料,在記憶體中都是瞬時的,會隨著斷電、關機等丟失資料,因此android系統采用了持久化技術,用于存盤這些“瞬時”資料 持久化技術包括:檔案存盤、SharedPreference存盤以及資料庫存盤,還有更復雜的SD卡記憶體儲。 二、檔案存盤 最基本存盤方式, ......

    uj5u.com 2020-09-10 07:00:47 more
  • Android Camera2Video整合到自己專案里

    背景: Android專案里呼叫攝像頭拍攝視頻,原本使用的 MediaStore.ACTION_VIDEO_CAPTURE, 后來因專案需要,改成了camera2 1.Camera2Video 官方demo有點問題,下載后,不能直接整合到專案 問題1.多次拍攝視頻崩潰 問題2.雙擊record按鈕, ......

    uj5u.com 2020-09-10 07:00:50 more
  • Android 開發技術周報 Issue#293

    新聞 谷歌為Android TV開發者提供多種新功能 Android 11將自動填表功能整合到鍵盤輸入建議中 谷歌宣布Android Auto即將支持更多的導航和數字停車應用 谷歌Pixel 5只有XL版本 搭載驍龍765G且將比Pixel 4更便宜 [圖]Wear OS將迎來重磅更新:應用啟動時間 ......

    uj5u.com 2020-09-10 07:01:38 more
  • 海豚星空掃碼投屏 Android 接收端 SDK 集成 六步驟

    掃碼投屏,開放網路,獨占設備,不需要額外下載軟體,微信掃碼,發現設備。支持標準DLNA協議,支持倍速播放。視頻,音頻,圖片投屏。好點意思。還支持自定義基于 DLNA 擴展的操作動作。好像要收費,沒體驗。 這里簡單記錄一下集成程序。 一 跟目錄的build.gradle添加私有mevan倉庫 mave ......

    uj5u.com 2020-09-10 07:01:43 more
最新发布
  • Flutter狀態管理新的實踐

    宣告式UI其實并不是近幾年的新技術,但是近幾年宣告式UI框架非常的火熱。單說移動端,跨平臺方案有:RN、Flutter。iOS原生有:SwiftUI。android原生有:compose。可以看到宣告式UI是以后的前端發展趨勢。而狀態管理是宣告式UI框架的重要組成部分。 ......

    uj5u.com 2023-06-21 08:53:40 more
  • Android Studio中SQLite的使用,主要介紹sqlite插入和讀出圖片(View

    sqlite簡介 本人最近在寫一個小的安卓專案,開發app程序中用到了安卓自帶的sqlite。本文主要對sqlite圖片操作進行介紹,其他存入文本之類的操作和普通資料庫一樣,眾所周知,sqlite是一款輕型的資料庫,以下先簡單介紹一下sqlite,為后續做鋪墊,有了解的大佬可以跳過此部分: SQLi ......

    uj5u.com 2023-06-20 09:33:03 more
  • Android程式員成長之路

    # 一、Android程式員需要具備的素養 1. 應該熱愛學習Android知識 2. 具備基本的自學能力和解決問題的能力 3. 具備實踐能力 # 二、Android程式員最終需要熟練掌握的語言 1. Java(基本) 2. C/C++(進階) 3. Kotlin(基本) 4. Python(可選) ......

    uj5u.com 2023-06-20 09:32:56 more
  • Airtest影像識別測驗工具原理解讀&最佳實踐

    Airtest是一個跨平臺的、基于影像識別的UI自動化測驗框架,適用于游戲和App,支持平臺有Windows、Android和iOS。Airtest框架基于一種圖形腳本語言Sikuli,參考該框架后,不再需要一行行的寫代碼,通過截取按鈕或輸入框的圖片,用圖片組成測驗場景,這種方式學習成本低,簡單易上... ......

    uj5u.com 2023-06-20 09:32:51 more
  • Android Studio中SQLite的使用,主要介紹sqlite插入和讀出圖片(View

    sqlite簡介 本人最近在寫一個小的安卓專案,開發app程序中用到了安卓自帶的sqlite。本文主要對sqlite圖片操作進行介紹,其他存入文本之類的操作和普通資料庫一樣,眾所周知,sqlite是一款輕型的資料庫,以下先簡單介紹一下sqlite,為后續做鋪墊,有了解的大佬可以跳過此部分: SQLi ......

    uj5u.com 2023-06-20 09:32:29 more
  • Android程式員成長之路

    # 一、Android程式員需要具備的素養 1. 應該熱愛學習Android知識 2. 具備基本的自學能力和解決問題的能力 3. 具備實踐能力 # 二、Android程式員最終需要熟練掌握的語言 1. Java(基本) 2. C/C++(進階) 3. Kotlin(基本) 4. Python(可選) ......

    uj5u.com 2023-06-20 09:32:23 more
  • Airtest影像識別測驗工具原理解讀&最佳實踐

    Airtest是一個跨平臺的、基于影像識別的UI自動化測驗框架,適用于游戲和App,支持平臺有Windows、Android和iOS。Airtest框架基于一種圖形腳本語言Sikuli,參考該框架后,不再需要一行行的寫代碼,通過截取按鈕或輸入框的圖片,用圖片組成測驗場景,這種方式學習成本低,簡單易上... ......

    uj5u.com 2023-06-20 09:32:16 more
  • Android-NDK開發——基本概念

    在Android開發中,有時候出于安全,性能,代碼共用的考慮,需要使用C/C++撰寫的庫。雖然在現代化工具鏈的支持下,這個作業的難度已經大大降低,但是畢竟萬事開頭難,初學者往往還是會遇到很多不可預測的問題。本篇就是基于此背景下寫的一份簡陋指南,希望能對剛開始撰寫C/C++庫的讀者有所幫助。同時為了盡 ......

    uj5u.com 2023-06-18 08:09:33 more
  • Android-JNI開發概論

    ### 什么是JNI開發 JNI的全稱是Java Native Interface,顧名思義,這是一種解決Java和C/C++相互呼叫的編程方式。**它其實只解決兩個方面的問題,怎么找到和怎么訪問。** 弄清楚這兩個話題,我們就學會了JNI開發。**需要注意的是,JNI開發只涉及到一小部分C/C++ ......

    uj5u.com 2023-06-18 08:09:29 more
  • Android-NDK開發——基本概念

    在Android開發中,有時候出于安全,性能,代碼共用的考慮,需要使用C/C++撰寫的庫。雖然在現代化工具鏈的支持下,這個作業的難度已經大大降低,但是畢竟萬事開頭難,初學者往往還是會遇到很多不可預測的問題。本篇就是基于此背景下寫的一份簡陋指南,希望能對剛開始撰寫C/C++庫的讀者有所幫助。同時為了盡 ......

    uj5u.com 2023-06-18 08:09:06 more