這種方法最常見,但是有些地方引用的話,刷新的成本比較大,刷新的是整個頁面,數(shù)據(jù)太多加載太慢的話,會有閃爍的現(xiàn)象
讓客戶滿意是我們工作的目標(biāo),不斷超越客戶的期望值來自于我們對這個行業(yè)的熱愛。我們立志把好的技術(shù)通過有效、簡單的方式提供給客戶,將通過不懈努力成為客戶在信息化領(lǐng)域值得信任、有價值的長期合作伙伴,公司提供的服務(wù)項目有:申請域名、虛擬空間、營銷軟件、網(wǎng)站建設(shè)、河南網(wǎng)站維護(hù)、網(wǎng)站推廣。
這種方法類似于iOS中的set方法,通過設(shè)置某個屬性的時候,去刷新某個控件。在flutter中這種刷新方式,是對上面setState(){}方法的改進(jìn),根本的方法還是setState(){},只不過是通過方法去刷新某個控件。如下:
首先在pubspec.yaml中添加provider依賴
下面通過provider來實現(xiàn)一個發(fā)送驗證碼的案例。
創(chuàng)建一個TimerModel文件
頁面布局如下:
在Tree中從上往下高效傳遞數(shù)據(jù)的基類widget , 定義為:abstract class InheritedWidget extends ProxyWidget
Flutter的響應(yīng)式開發(fā)與React類似,數(shù)據(jù)都是自頂向下的。
假設(shè)有祖先組點A,中間經(jīng)過結(jié)點B, C,然后到結(jié)點D,D需要從A中獲取數(shù)據(jù)f,那按照自頂向下數(shù)據(jù)流轉(zhuǎn),f需要依次傳遞給B及C,最后才到C。這樣開發(fā)極為不靈活,成本也比較高。所有Flutter需要有跨結(jié)點(只能是祖先后代節(jié)點,不能跨兄弟節(jié)點)高效傳遞數(shù)據(jù)的方案。
大體意思如下:
InheritedWidget 是在樹中高效向下傳遞信息的基類部件;
調(diào)用[BuildContext.inheritFromWidgetOfExactType]方法可以從 BuildContext 中獲取到最近的 InheritedWidget 類型的實例;
在 InheritedWidget 類型的控件被引用,也就是調(diào)用過 inheritFromWidgetOfExactType 方法后,當(dāng) InheritedWidget 自身狀態(tài)改變時,會導(dǎo)致引用了 InheritedWidget 類型的子控件重構(gòu)(rebuild)。
這里隨便定義一個人 Person 類。
創(chuàng)建一個類繼承 InheritedWidget,并實現(xiàn) updateShouldNotify 方法。
之前說到調(diào)用[BuildContext.inheritFromWidgetOfExactType]方法可以從 BuildContext 中獲取到最近的 InheritedWidget 類型的實例,所以此處定義一個靜態(tài)的 of 方法,通過傳入的 context 獲取到最近的 InheriedDataWidget 實例。
1.定義數(shù)據(jù)模型
這里隨便定義一個 Person 類。
2.自定義 InheritedWidget 控件類
創(chuàng)建一個類繼承 InheritedWidget,并實現(xiàn) updateShouldNotify 方法。
之前說到調(diào)用[BuildContext.inheritFromWidgetOfExactType]方法可以從 BuildContext 中獲取到最近的 InheritedWidget 類型的實例,所以此處定義一個靜態(tài)的 of 方法,通過傳入的 context 獲取到最近的 InheriedDataWidget 實例。
3.InheriedDataWidget 的使用
InheriedDataWidget 使用起來也很簡單,它本身也是一個控件,只要在任意一個頁面的子控件調(diào)用其構(gòu)造方法就行,這里我們定義一個形如的 Widget 樹。
WidgetA 是一個 StatefulWidget 類型的控件,可以調(diào)用 setState 刷新,如果是繼承人 Stateless 類型的控件,那我們也可以通過 Stream 或者其他方式刷新數(shù)據(jù),感興趣的請看[什么是 Stream? Dart
WidgetA1_1 類
WidgetA1_2 類
WidgetA1_3 類
當(dāng)我們點擊 floatingActionButton 的時候,WidgetA1, WidgetA1_1, WidgetA1_2 的控件都會更新 Person 的信息,而且每點 floatingActionButton 一次, 當(dāng)我們點擊 floatingActionButton 的時候,WidgetA1, WidgetA1_1, WidgetA1_2 的控件都會更新 Person 的信息,而且每點 floatingActionButton 一次,都會輸出:
如果我們試圖在和 WidgetA 的同一層級的兄弟節(jié)點去訪問 InheriedDataWidget 的 Person 數(shù)據(jù),是不行的,因為父節(jié)點中并沒有插入 InheriedDataWidget。
把 WidgetB 和 WidgetA 保持同一節(jié)點
這也體現(xiàn)了 Inheried(遺傳) 這一單詞的特性,遺傳只存在于父子。兄弟不存在遺傳的關(guān)系。
這種數(shù)據(jù)共享的方式在某些場景還是很有用的,就比如說全局主題,字體大小,字體顏色的變更,只要在 App 根層級共享出這些配置數(shù)據(jù),然后在觸發(fā)數(shù)據(jù)改變之后,所有引用到這些共享數(shù)據(jù)的地方都會刷新,這換主題,字體是不是就很輕松,事實上 Theme.of(context).primaryColor 之流就是這么干的。
以上就是有關(guān)InheritedWidget的使用。
自己也是從事Android開發(fā)5年有余了;整理了一些Android開發(fā)技術(shù)核心筆記和面經(jīng)題綱,有關(guān)更多Android開發(fā)進(jìn)階技術(shù)資料、面經(jīng)題綱、核心技術(shù)筆記; 想要進(jìn)階自己、拿高薪的同學(xué)請私信我回復(fù)“核心筆記”或“面試”領(lǐng)??!
在編寫幾個 Flutter 項目后,發(fā)現(xiàn) Flutter 的強(qiáng)大之處在于業(yè)務(wù)中所有用到的控件以及場景都有對應(yīng)的處理方案;而 Dart 語言也與 Java 、 Kotlin 類似,所以對 Android 開發(fā)者來說門檻非常低;特意記錄一下常用的控件及其使用:
StatelessWidget 不需要額外的創(chuàng)建 State
StatefulWidget 創(chuàng)建 State 類,并可以在其中保存一些狀態(tài)
only 可以單獨設(shè)置每個方向的內(nèi)邊距
類似于 LinearLayout 中的 orientation 設(shè)置為 vertical , mainAxisAlignment 表示豎向的一個對齊方式, crossAxisAlignment 表示橫向的對齊方式
與 Column 相反,主軸是橫向,對齊方式類似, crossAxisAlignment 表示豎向的對齊方式
類似 SizedBox ,一個容器,但是主要功能是有一個 decoration —— 裝飾器,作用是繪制背景,或者使用 item 中的陰影
棧,先入后出,類似于 Android 上的 FrameLayout
通常配合 Stack 使用,固定顯示在某一個位置
配合多 child 使用,會填充剩余的空間
Image 功能強(qiáng)大,使用不同的方法可以加載不同來源的圖片
看到這些方法,突然覺得 Flutter 太香了,而且 Image 可以配置 clip 等裁剪出不同形狀的圖片,無論是圓形還是五角星都不在話下,然而 Android 要實現(xiàn)不規(guī)則的形狀,可是要下不少功夫的。
名字和 Android 的一模一樣,但是用法卻比 Android 的簡單很多:
主要就是 itemCount 與 itemBuilder ,其余就是配置樣式, itemBuilder 需要返回一個 widget ,當(dāng)然了,每個 ListView 都有其對應(yīng)的 item ,在里面的方法中編寫 widget 即可
與 ListView 類似,但是需要有一個 delegate 類,作用是設(shè)置有多少列,每一列之間的間距是多少
GridView 沒有 build , children 表示所有的子 view
最常用的控件之一,有非常多的樣式, Flutter 中通常是使用裝飾器來處理控件的,如背景使用 BoxDecoration , TextFiled 使用 InputDecoration ; 使用如下
Flutter是谷歌公司推出的跨終端的開發(fā)框架,支持Android、iOS和WEB終端。1.0版在2018年12月5日發(fā)布,目前的最新版本是1.5,它采用的開發(fā)語言是Dart,Dart也是谷歌開發(fā)的計算機(jī)編程語言,語法類似C,是編譯型語言:
hello world例子,打印字符串“Hello World!”:
1、沒有橋接層
React Native、Weex等技術(shù)都是跨終端的框架,然而性能跟原生App存在很大差距。這是由于它們的工作原理決定的:
React Native、Weex等技術(shù)多了一個橋接層,所以界面渲染會慢一些,由于UI渲染非常頻繁,想要不卡頓,基本上比較難,性能和用戶體驗跟原生代碼有差距。而這恰恰是Flutter的優(yōu)勢所在:
Dart可以被編譯成不同平臺的本地代碼,讓Flutter不通過橋接層直接跟平臺通信,自然性能會快一些。
2、編譯執(zhí)行
JavaScript是解釋執(zhí)行的,Dart是編譯執(zhí)行的,性能誰好一目了然。
3、Flutter Engine虛擬機(jī)
Flutter是依靠Flutter Engine虛擬機(jī)在iOS和Android上運(yùn)行的,F(xiàn)lutter Engine使用C/C++編寫,開發(fā)人員通過Flutter框架直接和API在內(nèi)部進(jìn)行交互,所以具有輸入低延遲和UI渲染高幀速率的特點。除了這特點之外,F(xiàn)lutter還提供了自己的小部件,F(xiàn)lutter小部件是使用從React獲取靈感的現(xiàn)代框架構(gòu)建的。 中心思想是您使用小部件構(gòu)建UI。
窗口小部件根據(jù)其當(dāng)前配置和狀態(tài)描述了它們的視圖。 當(dāng)窗口小部件的狀態(tài)發(fā)生更改時,窗口小部件會重建其描述,框架將根據(jù)前面的描述進(jìn)行區(qū)分,以確定底層呈現(xiàn)樹從一個狀態(tài)轉(zhuǎn)換到下一個狀態(tài)所需的最小更改??梢灾苯釉贠S平臺提供的畫布上進(jìn)行描繪,也就是一些核心類庫直接放到虛擬機(jī)里面,調(diào)用起來更快。
從它的系統(tǒng)結(jié)構(gòu)可以看出,類似安卓的ART(Android Run Time)虛擬機(jī),同樣采用AOT(Ahead of TIme)技術(shù),會在APP安裝時就編譯成機(jī)器語言,不再解釋執(zhí)行,從而優(yōu)化了APP運(yùn)行的性能。
4、自帶渲染引擎
Flutter使用谷歌自己的Skia渲染引擎,而Android系統(tǒng)自帶Skia引擎,iOS平臺上Flutter也會把Skia引擎打包到APP中,從而實現(xiàn)了高效渲染。而React Native通過橋接層訪問原生UI,操作頻繁就容易出性能問題。
綜合所述,F(xiàn)lutter 是性能最接近原生代碼 的一種開發(fā)框架,未來也會是構(gòu)建谷歌Fuchsia應(yīng)用的主要方式,前途不可限量,唯一的問題就是需要學(xué)習(xí)一門新的語言:Dart,而有Java或者C#語言基礎(chǔ)的程序員會比較容易學(xué)習(xí)。
TextFormField繼承自FormField,是flutter表單提交相關(guān)組件,類似于html中的 input type="text" / ,是個文本輸入框。需要在 Form 組件內(nèi)部使用,否則無法正確提交數(shù)據(jù)。
未完待續(xù)
不久前,谷歌正式推出 Jetpack Compose 1.0 版本。近日,JetBrains 在此基礎(chǔ)上發(fā)布了 Compose Multiplatform Alpha 版本,旨在將 Compose 擴(kuò)展到桌面和 Web 端。
Compose Multiplatform 由 Compose for Desktop 和 Compose for Web 組成,通過 Kotlin Multiplatform 支持許多不同的平臺。其中,Compose Desktop 采用 Google 的 Skia 圖形庫,來實現(xiàn)在 Windows、macOS 和 Linux 上的 UI 繪制,借此在所有支持的操作系統(tǒng)中提供統(tǒng)一的體驗,類似于 Flutter 的做法。
根據(jù) Kotlin 團(tuán)隊的說法,相比起 Electron 框架,Compose Multiplatform 在內(nèi)存消耗、安裝大小和 UI 渲染性能等方面將有更明顯的優(yōu)勢。隨著 Alpha 版本的發(fā)布,Compose Multiplatform 還收獲了新的 Android Studio 插件,包括對在 IDE 中顯示組件預(yù)覽的支持以及許多附加功能。
我們希望通過本文幫助大家進(jìn)一步了解 Compose 的跨平臺能力,以及 JetBrains 將 Compose 從 Android 擴(kuò)展到這些其他平臺背后的主要驅(qū)動力是什么。
基于 Jetpack Compose 1.0
由谷歌打造的 Jetpack Compose 是一款用于在 Android 應(yīng)用程序之內(nèi)構(gòu)建用戶界面的官方框架,上周剛剛發(fā)布 1.0 版本。與此同時,Android Studio 代號“極狐”的首個穩(wěn)定版 2020.3.1 也正式亮相。
盡管才剛迎來 1.0,但谷歌表示“目前 Play Store 中已經(jīng)有超過 2000 款應(yīng)用程序在使用 Compose——更重要的是,就連 Play Store 這款應(yīng)用本身也在使用 Compose。”谷歌方面還表示,“我們一直在與一些頂級應(yīng)用的開發(fā)人員進(jìn)行合作,他們的反饋和支持幫助我們使 1.0 版本更加強(qiáng)大?!?/p>
Jetpack Compose for Android 迎來 1.0 版本
Compose 基于 Kotlin 開發(fā),而 Kotlin 與 Android Studio(即官方指定的 Android IDE)均來自開發(fā)工具廠商 JetBrains。雖然 Jetpack Compose 專為 Android 打造(與谷歌的 Flutter 框架不同), 但 JetBrains 公司堅信 Compose 完全能夠獲得跨平臺能力 。
Compose for Desktop: 這只是開始
Compose Multiplatform 可以說是該框架面向 MacOS、Linux、Windows 以及 Web 開設(shè)的一個端口,目前剛剛發(fā)布 1.0 Alpha 版本。雖然尚處于早期開發(fā)階段,但 JetBrains 表示,其已經(jīng)“為開發(fā)人員帶來能夠基本安全使用的穩(wěn)定 API”。
TheRegister 就此事詢問了 JetBrains 公司 Compose 項目負(fù)責(zé)人 Nikolay Igotti,希望了解為什么該公司在擁有了已經(jīng)廣泛應(yīng)用于 IntelliJ IDEA IDE 及多種豐富變體的桌面應(yīng)用程序跨平臺 Java 框架之外,還要費(fèi)力開發(fā) Compose for Desktop。Igotti 的回答是,“舊有 Java 框架基本上就是修改版的 Swing。Swing 屬于默認(rèn) JDK UI 框架,Swing 和 AWT(Abstract Windows Toolkit,抽象窗口工具包)。Compose 則完全是另一碼事,當(dāng)然我們也在設(shè)計中考慮到了互操作性需求……Swing 這套框架太陳舊了,最早出現(xiàn)在上世紀(jì)九十年代末。多年來人們對于 UI 的設(shè)計思路已經(jīng)天翻地覆,Swing 顯然滿足不了要求了。”
JetBrains IDE 中的 Compose for Desktop 項目
Compose 與 Swing 有一個比較大的共同點:與其他使用本機(jī)控件的跨平臺框架,比如例如 Java 的 SWT(Standard Widget Toolkit)以及微軟的 Xamarin 有所不同,它們選擇自主繪制控件。Compose 使用的 Skia 開源圖形庫,也在谷歌 Chrome、Flutter 及其他眾多框架當(dāng)中得到廣泛應(yīng)用。那這是否意味著 Compose 應(yīng)用程序?qū)]有自己的原生外觀?對此,Igotti 的回應(yīng)是,“這取決于開發(fā)人員的選擇,取決于他們?nèi)绾螢閼?yīng)用程序設(shè)置主題。在這方面,Compose 的情況與 Flutter 等其他框架沒什么區(qū)別?!?/p>
那 Compose for Desktop 應(yīng)用程序是否依賴于 JVM(Java Virtual Machine)運(yùn)行?Igotti 表示,“我們也知道,JVM 應(yīng)用程序的發(fā)布情況可能比較棘手。因此我們提供自己的 Gradle 插件,其使用 jpackage 與 Jlink 以 JVM 應(yīng)用程序為基礎(chǔ)制作原生應(yīng)用程序。Mac 的.dmg、Windows 的 MSI、Linux 的 deb 包等均可實現(xiàn),大家用不著擔(dān)心 JVM?!?/p>
也就是說,開發(fā)成果將會是一款被精心包裹起來的 JVM 應(yīng)用程序。JetBrains 還有一款用于解決這個問題的 Kotlin/Native 編譯器,“預(yù)計將在未來發(fā)布,或者專門用于桌面開發(fā)?!?/p>
對應(yīng)用程序的另一種思考方式
那 Web 應(yīng)用程序方面呢?Igotti 回應(yīng)稱,“我們使用 Kotlin/JS 編譯器?!盋ompose 的 Web 版本不如桌面版先進(jìn),說明文檔中也警告稱“API 尚未最終確定,預(yù)計會發(fā)生重大變化?!贝送?,雖然 Web 版本確實使用 Compose 模型,但 API 卻完全不同,而且會使用 HTML 與 CSS。所以,Web 版與 Compose for Desktop 之間能夠共享的代碼應(yīng)該比較少。
據(jù) Igotti 介紹,“Compose 代表著一種不同的應(yīng)用程序思考方式。狀態(tài)即 UI 的真實來源,而 UI 本身是無狀態(tài)的,其表達(dá)永遠(yuǎn)由狀態(tài)計算得出。在這方面,Compose for Web 采用一組相同的原語,完全相同的狀態(tài)管理思路。但是對于具體的小部件集合與排列方式,Web 版與桌面版之間確實無法互通?!?/p>
說到這里,為什么要把 Compose for Android 擴(kuò)展到多種其他平臺之上?“Compose 的目標(biāo)受眾主要分為三類。首先是使用 Kotlin 與 Compose 的 Android 開發(fā)人員,他們希望把自己的開發(fā)成果交付至其他平臺;其二是純 Kotlin 開發(fā)人員,他們希望以‘一次編寫、隨處運(yùn)行’的方式開發(fā)新的應(yīng)用程序;第三則是那些不太熟悉 Kotlin 或者 Compose,但又希望開發(fā)出精美 UI 的用戶,我們希望能為他們提供實現(xiàn)目標(biāo)的工具。”
Igotti 并沒有給出具體的發(fā)布日期,但表示自己希望 Beta 版能在今年秋天發(fā)布,“我們也希望能在今年之內(nèi)推出 1.0 版本。”項目本身是完全開源的,“二十一世紀(jì)了,框架在大多數(shù)人們心目中就不應(yīng)該收費(fèi)。我們只是想開發(fā)一款長期缺失的軟件”,補(bǔ)足 JetBrains 當(dāng)前商業(yè)模式中的工具鏈。
那么,JetBrains 會在自己的其他工具中使用 Compose 嗎?事實上,他們的 JetBrains Toolbox(用于管理已安裝的 IDE)已經(jīng)在使用 Compose,但 Igotti 表示短時間內(nèi) Compose 還無法取代 IntelliJ IDEA 等現(xiàn)有框架?!熬庉嬈魇瞧渲凶顝?fù)雜也最重要的組件,經(jīng)歷了 20 年的發(fā)展演進(jìn),我們幾乎不可能在中途進(jìn)行重寫了。無論是 JetBrains 還是我個人,都不打算強(qiáng)迫每個人都轉(zhuǎn)而使用 Compose。我們的目標(biāo)是為原有框架選項滿足不了的用戶提供新的解決方案?!?/p>
寫在最后
那么,為什么除了 Flutter 之外,我們還需要另一個跨平臺框架?雖然谷歌的 Flutter 最開始主要面向移動設(shè)備,但現(xiàn)在也開始向桌面及 iOS 進(jìn)軍,甚至比 Compose 還搶先了一步。不過,根據(jù) StackOverflow 的最新調(diào)查, Flutter 使用的語言為 Dart;盡管 Dart 語言的人氣正在增長(正是受到 Flutter 的推動),但仍然無法與 Kotlin 相提并論。
Compose 代表著一種獨特的 UI 構(gòu)建方法,也許最期待 Compose 跨平臺功能的受眾,正是那些曾在 Android 上使用過它、又特別喜歡這種 UI 構(gòu)建體驗的開發(fā)者。
想要進(jìn)一步了解 Compose,國內(nèi) Android 開發(fā)者可訪問以下鏈接查看中文手冊:
延伸閱讀: