還在寫iOS?是時候學一下Flutter了

文章概述

本人以前主要從事iOS開發工做,恰好Flutter文檔中有一篇Flutter for iOS developers的文檔,以前兩篇文章,咱們大體上體驗了Flutter,這篇文中我將從iOS開發者的角度來學習Flutter,與官方文檔不一樣的是,這篇文章會更注重實踐。因爲文檔很長,我將用兩篇文章講解。這是第一篇。經過閱讀本篇文章,你講學習到以下內容:ios

  • Widget與UIView的區別。
  • 導航,如何在頁面間跳轉

Widget與UIView

對於咱們iOS開發者來說,UIView再熟悉不過,它是咱們構建界面的必備元素。而在Flutter中,咱們能夠將Widget看作是UIView,但它與UIView並非徹底等價的。git

對於Widget而言,它是不可變的,當Widget所描述的界面須要改變的時候,Flutter是從新構建一個Widget實現的。對於UIView而言,界面改變的時候並非去從新繪製(除非調用setNeedsDisplay()方法),而是屬性的改變。github

更確切的說,Widget更輕量級,由於它是不可變的。它只是UI的描述,是對下層真實視圖對象的描述,而不是視圖自己,也不會去繪製任何東西。objective-c

Flutter包含 Material Components組件庫。這是一個遵循 Material Design guidelines 規範實現的控件,這是一個很是靈活的設計系統,並針對全部的系統進行了優化,包含iOS系統。算法

咱們可使用 Cupertino widgets 組件來實現遵循 Apple’s iOS design language 的界面。微信

如何更新Widgets

Flutter中更新widgets須要去操做它的state,不向UIView同樣,直接修改對象的屬性便可。Flutter中包含有狀態Widgets和無狀態Widgets,分別用StatefulWidgetStatelessWidget 表示。網絡

舉例來講:若是你只須要展現一個圖標,而且它不會被改變,這時使用StatelessWidget 便可完成,但若是你須要根據網絡請求返回的結果來動態的設置圖片就須要使用StatefulWidget來完成了。app

StatefulWidgetStatelessWidget的最大區別是,StatefulWidget擁有一個存儲狀態數據的State對象,而且在整個Widget Tree構建的過程當中一直攜帶者它,永不丟失。less

有一個簡單的記法:若是一個Widget在它的build方法以外改變,它就是有狀態的,若是在第一次構建以後永不改變,它就是無狀態的。一個有狀態的Widget的父控件能夠是無狀態的,只要父控件不受子控件狀態的影響便可。如Text就是一個無狀態的Widget組件。ide

// class Text extends StatelessWidget
Text(
  'I like Flutter!',
  style: TextStyle(fontWeight: FontWeight.bold),
);
複製代碼

不難發現Text沒有攜帶任何狀態信息,只有經過構造函數傳遞的信息。

若是要實現經過點擊事件來改變Text的文本信息,須要經過將Text用StatefulWidget包裹一下來實現,

代碼以下:

flutter佈局.png

效果以下:

改變文本內容.gif

如何對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:

flutter佈局.png

代碼效果以下:

![佈局效果圖.jpg](https://test.demo-1s.com/images/2019/05/18/kqr78c99LPRXDpAz.jpg)

你能夠對任何一個Widget使用padding屬性,它模擬了iOS中的約束功能。

widget layout這篇文章詳細介紹了Flutter所提供的佈局功能。

如何從佈局中添加或者刪除一個組件

在iOS中,咱們能夠調用父視圖的addSubview() 方法爲父視圖添加能夠子視圖,或者調用子視圖的removeFromSuperview()方法將自身從其父視圖中移除,經過以上兩個方法能夠動態的添加或者移除子視圖。在Flutter中,因爲widget是不可變的,沒有與addSubvie()等價的功能函數。在flutter中可使用一個bool型變量來控制子視圖是否須要建立。

來看下面的例子:經過一個toggle變量來控制子視圖顯示的內容:

更新子視圖.png

效果以下:

變動子視圖.gif

如何設置Widget 動畫

在iOS中咱們可使用animate(withDuration:animations:)方法爲一個view設置動畫,在Flutter中須要使用第三方庫來包裝widget而不是使用具體動畫屬性的widge。

在Flutter中,使用AnimationController 它是Animation<double> 類型,能夠控制一個動畫的終止,執行,暫停和反轉。它須要一個Ticker ,當垂直同步信號時產生在它執行的每一幀都產生一個0到1之間的線性插值。你能夠建立一個或者多個動畫綁定到這個controller上。

舉個例子:

你可能使用CurvedAnimation依據插值曲線來完成一個動畫,在這種場景下,controller是動畫執行的"主人",CurvedAnimation計算用來計算的曲線會代替controller默認線性模式。

當構建widget樹你將Animation賦值給一個widget的動畫屬性,好比,FadeTransition的不透明度,而後告訴controller開始執行動畫。

下面的例子展現瞭如何寫一個淡出動畫,當點點擊了按鈕以後,logo會淡出顯示。

動畫.png

效果以下:

動畫.gif

更多動畫相關的資料能夠參考 Animation & Motion widgets, 和 Animations tutorial, 還有 Animations overview

如何繪製到屏幕上

在iOS中,咱們可使用CoreGraphics能夠將線條或者圖形繪製到屏幕上。Flutter中擁有一套不一樣的Api,它基於Canvas這個類,並結合 CustomPaintCustomPainter 兩個類能夠幫你實現屏幕繪製需求,CustomPainter 實現了繪製畫布的算法。

在Flutter中,實現畫筆程序 能夠參考Collin 在 StackOverflow 上的答案,源碼在kitttn‘s github

Flutter畫筆.png
\

效果以下:

畫筆.gif

widget的透明度在哪

在iOS中每一個組件都有.opacity 或者 .alpha 屬性表示透明度。在Flutter中,要是先透明須要使用透明的widget包裝一下widget才能實現。

如何實現自定義widget

在iOS中,咱們能夠繼承UIView,或者使用已經存在的視圖,經過從新和實現方法來實現指望的行爲。在Flutter中,構造一個自定的widget須要將系統提供的widget組合在一塊兒。

舉個例子:如何自定義一個CustomButton, 它的構造方法中攜帶一個label?能夠經過將RaisedButton和label結合在一塊兒,以下代碼:

自定義widget.png

導航

如何在多個頁面之間跳轉

在iOS中,多個viewController之間的轉化能夠經過UINavigationController來實現,它管理着一組viewController的顯示。

Flutter中有相似的實現,使用NavigatorRouter來實現,一個Router是一個app中screen或者page的抽象,Navigator是一個widget,它管理着多個router。router近似於iOS中的UIViewController,navigator的工做機制和iOS中的UINavigationController一致。因此它可使用push()pop()來將頁面導航到某個視圖或者返回到某個視圖。

在頁面之間跳轉,你可使用下面的幾個方式:

  • 指定一個由router名稱構成的map。
  • 直接跳轉到一個路由

頁面跳轉.png

如何跳轉到另外一個app

在 iOS 中,要跳轉到其餘 App,你須要一個特定的 URL Scheme。對系統級別的 App 來講,這個 scheme 取決於 App。爲了在 Flutter 中實現這個功能,你能夠建立一個原平生臺的整合層,或者使用現有的 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開發者的角度講述了Flutter開發中的幾個點,不知道你是否有所收穫,本文還有第二篇文章,敬請期待。

本文主要參考Flutter官方文檔Flutter中文網

因爲排版緣由,文中我使用了圖片的形式展現代碼,若是你須要源碼,能夠關注個人公衆號,回覆關鍵字"flutter"獲取相關代碼。

本文首發自微信公衆號【RiverLi】,歡迎你的關注與投稿。

相關文章
相關標籤/搜索