文章概述
本人之前主要從事iOS開發(fā)工作饵骨,剛好Flutter文檔中有一篇Flutter for iOS developers的文檔翘悉,之前兩篇文章,我們大致上體驗了Flutter居触,這篇文中我將從iOS開發(fā)者的角度來學習Flutter妖混,與官方文檔不同的是,這篇文章會更注重實踐轮洋。由于文檔很長制市,我將用兩篇文章講解。這是第一篇弊予。通過閱讀本篇文章祥楣,你講學習到如下內容:
- Widget與UIView的區(qū)別。
- 導航,如何在頁面間跳轉
Widget與UIView
對于我們iOS開發(fā)者來講误褪,UIView
再熟悉不過责鳍,它是我們構建界面的必備元素。而在Flutter中兽间,我們可以將Widget
看做是UIView
历葛,但它與UIView
并不是完全等價的。
對于Widget而言嘀略,它是不可變的恤溶,當Widget所描述的界面需要改變的時候,F(xiàn)lutter是重新構建一個Widget實現(xiàn)的帜羊。對于UIView而言咒程,界面改變的時候并不是去重新繪制(除非調用setNeedsDisplay()方法),而是屬性的改變讼育。
更確切的說帐姻,Widget更輕量級,因為它是不可變的窥淆。它只是UI的描述卖宠,是對下層真實視圖對象的描述,而不是視圖本身忧饭,也不會去繪制任何東西扛伍。
Flutter包含 Material Components組件庫。這是一個遵循 Material Design guidelines 規(guī)范實現(xiàn)的控件词裤,這是一個非常靈活的設計系統(tǒng)刺洒,并針對所有的系統(tǒng)進行了優(yōu)化,包含iOS系統(tǒng)吼砂。
我們可以使用 Cupertino widgets 組件來實現(xiàn)遵循 Apple’s iOS design language 的界面逆航。
如何更新Widgets
Flutter中更新widgets需要去操作它的state,不向UIView一樣渔肩,直接修改對象的屬性即可因俐。Flutter中包含有狀態(tài)Widgets和無狀態(tài)Widgets,分別用StatefulWidget
和 StatelessWidget
表示周偎。
舉例來說:如果你只需要展示一個圖標抹剩,并且它不會被改變,這時使用StatelessWidget
即可完成蓉坎,但如果你需要根據(jù)網絡請求返回的結果來動態(tài)的設置圖片就需要使用StatefulWidget
來完成了澳眷。
StatefulWidget
和 StatelessWidget
的最大區(qū)別是,StatefulWidget
擁有一個存儲狀態(tài)數(shù)據(jù)的State
對象蛉艾,并且在整個Widget Tree構建的過程中一直攜帶者它钳踊,永不丟失衷敌。
有一個簡單的記法:如果一個Widget在它的build
方法之外改變,它就是有狀態(tài)的拓瞪,如果在第一次構建之后永不改變缴罗,它就是無狀態(tài)的。一個有狀態(tài)的Widget的父控件可以是無狀態(tài)的祭埂,只要父控件不受子控件狀態(tài)的影響即可瞒爬。如Text
就是一個無狀態(tài)的Widget組件。
// class Text extends StatelessWidget
Text(
'I like Flutter!',
style: TextStyle(fontWeight: FontWeight.bold),
);
不難發(fā)現(xiàn)Text沒有攜帶任何狀態(tài)信息沟堡,只有通過構造函數(shù)傳遞的信息。
如果要實現(xiàn)通過點擊事件來改變Text的文本信息矢空,需要通過將Text用StatefulWidget包裹一下來實現(xiàn)航罗,
代碼如下:
效果如下:
如何對Widget布局
In iOS, you might use a Storyboard file to organize your views and set constraints, or you might set your constraints programmatically in your view controllers. In Flutter, declare your layout in code by composing a widget tree.
The following example shows how to display a simple widget with padding:
在編寫iOS代碼的時候,你可以用Storyboard來構建視圖和設置約束屁药,或者在viewContoller中編寫約束代碼粥血。在Flutter中,我們將布局代碼寫在Widget樹種酿箭。
下面的例子展示了一個使用padding的Widget:
代碼效果如下:
![布局效果圖.jpg](https://upload-images.jianshu.io/upload_images/691666-99f93d3e3e89960e.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
你可以對任何一個Widget使用padding屬性复亏,它模擬了iOS中的約束功能。
widget layout這篇文章詳細介紹了Flutter所提供的布局功能缭嫡。
如何從布局中添加或者刪除一個組件
在iOS中缔御,我們可以調用父視圖的addSubview()
方法為父視圖添加可以子視圖,或者調用子視圖的removeFromSuperview()
方法將自身從其父視圖中移除妇蛀,通過以上兩個方法可以動態(tài)的添加或者移除子視圖耕突。在Flutter中,由于widget是不可變的评架,沒有與addSubvie()
等價的功能函數(shù)眷茁。在flutter中可以使用一個bool型變量來控制子視圖是否需要創(chuàng)建。
來看下面的例子:通過一個toggle變量來控制子視圖顯示的內容:
效果如下:
如何設置Widget 動畫
在iOS中我們可以使用animate(withDuration:animations:)
方法為一個view設置動畫纵诞,在Flutter中需要使用第三方庫來包裝widget而不是使用具體動畫屬性的widge上祈。
在Flutter中,使用AnimationController
它是Animation<double>
類型浙芙,可以控制一個動畫的終止登刺,執(zhí)行损谦,暫停和反轉流昏。它需要一個Ticker
霎褐,當垂直同步信號時產生在它執(zhí)行的每一幀都產生一個0到1之間的線性插值掰派。你可以創(chuàng)建一個或者多個動畫綁定到這個controller上色迂。
舉個例子:
你可能使用CurvedAnimation
依據(jù)插值曲線來完成一個動畫除呵,在這種場景下巧号,controller是動畫執(zhí)行的"主人"浓瞪,CurvedAnimation
計算用來計算的曲線會代替controller默認線性模式。
當構建widget樹你將Animation
賦值給一個widget的動畫屬性女轿,比如箭启,FadeTransition
的不透明度,然后告訴controller開始執(zhí)行動畫蛉迹。
下面的例子展示了如何寫一個淡出動畫傅寡,當點點擊了按鈕之后,logo會淡出顯示北救。
效果如下:
更多動畫相關的資料可以參考 Animation & Motion widgets, 和 Animations tutorial, 還有 Animations overview荐操。
如何繪制到屏幕上
在iOS中,我們可以使用CoreGraphics
可以將線條或者圖形繪制到屏幕上珍策。Flutter中擁有一套不同的Api托启,它基于Canvas
這個類,并結合 CustomPaint
和 CustomPainter
兩個類可以幫你實現(xiàn)屏幕繪制需求攘宙,CustomPainter
實現(xiàn)了繪制畫布的算法屯耸。
在Flutter中,實現(xiàn)畫筆程序 可以參考Collin 在 StackOverflow 上的答案蹭劈,源碼在kitttn‘s github
\
效果如下:
widget的透明度在哪
在iOS中每個組件都有.opacity 或者 .alpha 屬性表示透明度疗绣。在Flutter中,要是先透明需要使用透明的widget包裝一下widget才能實現(xiàn)铺韧。
如何實現(xiàn)自定義widget
在iOS中多矮,我們可以繼承UIView
,或者使用已經存在的視圖哈打,通過重新和實現(xiàn)方法來實現(xiàn)期望的行為工窍。在Flutter中,構造一個自定的widget需要將系統(tǒng)提供的widget組合在一起前酿。
舉個例子:如何自定義一個CustomButton
患雏, 它的構造方法中攜帶一個label?可以通過將RaisedButton
和label結合在一起罢维,如下代碼:
導航
如何在多個頁面之間跳轉
在iOS中淹仑,多個viewController之間的轉化可以通過UINavigationController
來實現(xiàn),它管理著一組viewController的顯示肺孵。
Flutter中有類似的實現(xiàn)匀借,使用Navigator
和Router
來實現(xiàn),一個Router
是一個app中screen
或者page
的抽象平窘,Navigator
是一個widget吓肋,它管理著多個router。router近似于iOS中的UIViewController瑰艘,navigator的工作機制和iOS中的UINavigationController
一致是鬼。所以它可以使用push()
和pop()
來將頁面導航到某個視圖或者返回到某個視圖肤舞。
在頁面之間跳轉,你可以使用下面的幾個方式:
- 指定一個由router名稱構成的map均蜜。
- 直接跳轉到一個路由
如何跳轉到另一個app
在 iOS 中李剖,要跳轉到其他 App,你需要一個特定的 URL Scheme囤耳。對系統(tǒng)級別的 App 來說篙顺,這個 scheme 取決于 App。為了在 Flutter 中實現(xiàn)這個功能充择,你可以創(chuàng)建一個原生平臺的整合層德玫,或者使用現(xiàn)有的 plugin,例如 url_launcher椎麦。
如何跳轉到iOS原生的viewController
調用SystemNavigator.pop()
方法相當于調用下面iOS代碼:
UIViewController* viewController = [UIApplication sharedApplication].keyWindow.rootViewController;
if ([viewController isKindOfClass:[UINavigationController class]]) {
[((UINavigationController*)viewController) popViewControllerAnimated:NO];
}
如果這樣達不到你的期望化焕,你可以寫自己的跨平臺方案來調用iOS代碼。platform channel
小結
本文主要從iOS開發(fā)者的角度講述了Flutter開發(fā)中的幾個點铃剔,不知道你是否有所收獲,本文還有第二篇文章查刻,敬請期待键兜。
本文主要參考Flutter官方文檔,Flutter中文網穗泵。