摘要:而在中,我們可以將看做是,但它與并不是完全等價的。中包含有狀態(tài)和無狀態(tài),分別用和表示。在中,由于是不可變的,沒有與等價的功能函數。在中,要是先透明需要使用透明的包裝一下才能實現(xiàn)。近似于中的,的工作機制和中的一致。
文章概述
本人之前主要從事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 的界面。
Flutter中更新widgets需要去操作它的state,不向UIView一樣,直接修改對象的屬性即可。Flutter中包含有狀態(tài)Widgets和無狀態(tài)Widgets,分別用StatefulWidget和 StatelessWidget 表示。
舉例來說:如果你只需要展示一個圖標,并且它不會被改變,這時使用StatelessWidget 即可完成,但如果你需要根據網絡請求返回的結果來動態(tài)的設置圖片就需要使用StatefulWidget來完成了。
StatefulWidget和 StatelessWidget的最大區(qū)別是,StatefulWidget擁有一個存儲狀態(tài)數據的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)信息,只有通過構造函數傳遞的信息。
如果要實現(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://test.demo-1s.com/images/2019/05/18/kqr78c99LPRXDpAz.jpg)
你可以對任何一個Widget使用padding屬性,它模擬了iOS中的約束功能。
widget layout這篇文章詳細介紹了Flutter所提供的布局功能。
如何從布局中添加或者刪除一個組件
在iOS中,我們可以調用父視圖的addSubview() 方法為父視圖添加可以子視圖,或者調用子視圖的removeFromSuperview()方法將自身從其父視圖中移除,通過以上兩個方法可以動態(tài)的添加或者移除子視圖。在Flutter中,由于widget是不可變的,沒有與addSubvie()等價的功能函數。在flutter中可以使用一個bool型變量來控制子視圖是否需要創(chuàng)建。
來看下面的例子:通過一個toggle變量來控制子視圖顯示的內容:
效果如下:
如何設置Widget 動畫
在iOS中我們可以使用animate(withDuration:animations:)方法為一個view設置動畫,在Flutter中需要使用第三方庫來包裝widget而不是使用具體動畫屬性的widge。
在Flutter中,使用AnimationController 它是Animation
舉個例子:
你可能使用CurvedAnimation依據插值曲線來完成一個動畫,在這種場景下,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。
直接跳轉到一個路由
在 iOS 中,要跳轉到其他 App,你需要一個特定的 URL Scheme。對系統(tǒng)級別的 App 來說,這個 scheme 取決于 App。為了在 Flutter 中實現(xiàn)這個功能,你可以創(chuàng)建一個原生平臺的整合層,或者使用現(xiàn)有的 plugin,例如 url_launcher。
調用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官方文檔,F(xiàn)lutter中文網。
由于排版原因,文中我使用了圖片的形式展示代碼,如果你需要源碼,可以關注我的公眾號,回復關鍵字"flutter"獲取相關代碼。
本文首發(fā)自微信公眾號【RiverLi】,歡迎你的關注與投稿。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉載請注明本文地址:http://systransis.cn/yun/7065.html
showImg(https://segmentfault.com/img/bVbw3tK?w=1240&h=827); 前端工程師這個崗位,真的是反人性的 我們來思考一個問題: 一個6年左右經驗的前端工程師: 前面兩年在用jQuery 期間一直在用React-native(一步一步踩坑過來的那種) 最近兩年還在寫微信小程序 下面一個2年經驗的前端工程師: 并不會跨平臺技術,他的兩年工作都是Reac...
摘要:在舒伯的生涯階段里有個確立階段,歲歲。知識技術安卓程序員需要掌握編程語言應用框架開發(fā)工具等這些具體的知識和技術。技術能力與閱歷對安卓程序員來講,知識技術是一方面,是容易習得的,是較淺的層面。 大齡程序員的界定 老早網上有人說,安卓開發(fā)干不過30歲,后來又有人說干不過35歲,后來又有人說干不過...
閱讀 736·2023-04-25 19:43
閱讀 3981·2021-11-30 14:52
閱讀 3807·2021-11-30 14:52
閱讀 3871·2021-11-29 11:00
閱讀 3802·2021-11-29 11:00
閱讀 3904·2021-11-29 11:00
閱讀 3580·2021-11-29 11:00
閱讀 6184·2021-11-29 11:00