8天讓iOS開發者上手Flutter之一:快速入門Flutter

franky發表於2021-07-10

flutter現在是越來越火了,現在作為一個iOS開發,如果你不會flutter都好像不算個正常人似的?而且現在的flutter情況,有點像2012年那會兒剛剛興起的iOS,Android開發一樣,會點皮毛UI就可以提升不少身價...這些年過來,有無數的前端跨平臺框架興起。卻只有flutter一家獨秀,說明它還是有兩把刷子的。今天這篇文章內容是基於Mac和Android Studio基礎來開發flutter的,如果你還沒有配置好開發環境,可以在網上搜尋,或者直接到官網安裝。這篇文章主要用來記錄我學習flutter的過程,如果你也對flutter感興趣可以跟著一起練習。

配置好Flutter環境之後,開始建立我們的第一個Flutter工程

建立第一個Flutter工程

開啟iTerm2,cd到~/AndroidStudioProjects目錄,輸入以下命令,沒有iTerms的使用Mac系統自帶的Terminal也行。
flutter create flutter_demo
這裡需要注意,AndroidStudio專案名稱不能使用大寫字母,這裡推薦使用小寫字母加下劃線給工程命名。 image.png 開啟對應的目錄,可以看到新建了一個flutter_demo目錄 image.png
接下來,cd到flutter_demo目錄,在終端輸入flutter run命令,它就會執行專案,如果你電腦連線了真機,就會自動執行到真機上,沒有真機會去尋找模擬器並執行,模擬器也沒有,就會開啟一個Chrome網頁執行專案(flutter專案目前可以執行在iOS,Android,web上)。我這裡連上了iPhone真機,執行專案會報一個BUILD FAILED的錯誤: image.png 原因是flutter_demo專案生成的iOS專案預設的bundle identifier我們們用不了,去iOS專案裡面修改一下就好了 image.png 這裡注意我們免費的開發者證書,在iPhone上最多安裝3個開發中的APP,多了就安裝不了,刪掉之前的APP就好了,再次執行flutter run image.png 可以看到這裡給出了flutter執行的一些關鍵命令,Hot reload熱過載,這個特性對我們開發UI時還是比原生的體驗好不少的,它不用我們重新執行專案就能看到UI的一些改變。Hot restart熱重啟,意思不用退出APP,就直接重新執行了。此時真機上就開啟了我們的第一個flutter工程的APP

8天讓iOS開發者上手Flutter之一:快速入門Flutter

HelloFlutter

上面是通過命令建立一個flutter專案,當然在實際開發過程我,我們一般不會這麼操作。使用Android Studio來建立flutter專案。沒有這個選項的同學,在Android Studio的外掛裡面選擇flutter並安裝就有了,如果提示還需要安裝Dart就一塊安裝了,flutter使用的是Dart語言。iOS開發者沒必要被這個新語言給嚇到了,現代的語言基本都差不了太多,敲著敲著就熟悉了 image.png 點選後會出現以下介面,目前我們選擇Flutter App就好了 image.png 下一個介面會讓我們設定工程名稱,工程位置,工程描述,工程組織,Android語言,iOS語言等等...我這裡設定工程名稱為hello_flutter,其他的預設選擇就好了...也可以根據你自己的需要選擇 image.png 點選Finish之後就可以看到完整的工程目錄了,flutter工程的主入口,跟我們iOS專案一樣有一個main.m檔案,flutter的是main.dart檔案,可以看到這個檔案裡面已經有不少初始的程式碼了,今天是我們第一次接觸flutter專案,就不要這裡的程式碼,全部刪掉,我們從第一行程式碼開始自己敲出來 image.png

image.png

  • 匯入material.dart標頭檔案(相當於iOS中UIKit)
  • 寫一個main()函式作為主入口
  • 呼叫runAPP()函式
  • Center類是用來佈局的類,表示一個位置,child屬性表示他有的子控制元件的意思。Text類就是我們文字類,有點兒我們iOS的UILabel的意思,Text類的第一個引數就是具體的文字,省略了引數名,第二個引數textDirection表示文字顯示方向,我們習慣的從左至右就是TextDirection.ltr,left to right。像一些阿拉伯語言,希伯來語的文字就是從右到左顯示的,我這裡試了一下hello world的方向並沒有變化,可能還需要其他設定吧...

執行之後iPhone顯示如下:

8天讓iOS開發者上手Flutter之一:快速入門Flutter

自定義Widget

flutter裡面的Widget類叫作小部件,是flutter裡面經常用到的,它分為有狀態的Stateful和Stateless無狀態的。其中無狀態的比較簡單,我們先自定義一個類CustomWidget繼承自StatelessWidget。我們自定義的Widget想要顯示到螢幕上需要實現一個build的函式,系統會呼叫這個函式來渲染我們想要顯示到螢幕上的內容 image.png 這個時候,如何將我們的hello flutter顯示到螢幕呢,可以看到runApp函式裡面有一個Center類,我們CustomWidget類的build方法也是返回的一個Center類,所以可以直接將我們CustomWidget初始化給runApp作引數 image.png 有些時候,我們發現hot reload無法更新介面,可以使用hot restart,如果hot restart還是無法更新介面,那就需要重新執行一下就可以了。此時我們發現main()函式裡面就只有一句呼叫runApp()程式碼,在Dart語言中,函式定義如果只有一句程式碼,那麼可以省略成如下箭頭形式 image.png

設定文字樣式style

按住command再用滑鼠左鍵點選Text類,就會跳到一個text.dart檔案,會看到一個this.style屬性,再次按住command點選,會來到style的宣告部分: image.png 這裡的final表示不可變,常量的意思,類似於Swift裡面的let。可以看到style是一個TextStyle型別,檢視TextStyle類,會發現裡面很多的屬性,比如color,backgroundColor,fontSize,fontWeight...這些都是很熟悉的屬性,接下來我們設定一下hello flutter的一些文字樣式 image.png 使用Android Studio快捷鍵command + \檢視介面

8天讓iOS開發者上手Flutter之一:快速入門Flutter

Material App

在flutter提供的標頭檔案material.dart中,提供了一個快速構建APP的型別MaterialApp,我們可以使用它來快速構建一個APP的基礎框架。
我們先新建一個App類來寫我們的程式碼 image.png
然後我們在App的build方法中,返回一個MaterialApp類,如果MaterialApp不傳入任何引數的話,執行後會發現APP整個螢幕變成紅色,並且顯示了一行文字,意思是出錯了之類的,說明我們的MaterialApp應該是需要傳入一個必要的引數的。 image.png 沒錯就像我們iOS的APP同樣需要一個rootViewController一樣,MaterialApp函式需要一個home引數,home引數可以傳一個Widget類,如果傳入我們剛剛寫的CustomWidget類,執行後發現有了一點不一樣的地方

8天讓iOS開發者上手Flutter之一:快速入門Flutter
右上角有一個debug的圖示,hello flutter下面也出現了兩條橫線。

flutter還提供了一個Scaffold的類,這個類翻譯過來叫作腳手架,有點像是我們iOS中的一些基礎控制器(比如UITabBarController,UINavigationController)的封裝。我們來使用一下這個類,這個Scaffold類有一個appBar的屬性,這個屬性就跟我們的UINavigationController的UINavigationBar一樣,appBar是一個AppBar型別,它的title屬性可以傳入一個Widget,我們傳入一個Text類試試看。Scaffold類除了appBar屬性,還有一個body屬性表示的內容,把這個body設定為我們剛剛的CustomWidget,看看是什麼效果,程式碼如下: image.png APP上顯示效果:

8天讓iOS開發者上手Flutter之一:快速入門Flutter
這個時候,是不是發現像那麼回事了

MaterialApp還有一個theme的屬性,這個屬性用了配置app的主題,設定一下主題顏色程式碼如下: image.png APP上顯示效果:

8天讓iOS開發者上手Flutter之一:快速入門Flutter

初探ListView

在探索ListView之前,我們先把模型實現一下,我們這裡展示的一組關於汽車的圖片和名字,就定義一個Car類,我們新建一個car檔案用來存放我們的模型程式碼,程式碼如下: image.png

再定義一個陣列,用來存放一組汽車模型,我這裡放了一組網路圖片,你可以直接使用,也可以自己在網上找幾張圖片,填入模型陣列中

final List<Car> cars = [
  Car(
    name: '保時捷918 Spyder',
    imageUrl:
    'https://upload-images.jianshu.io/upload_images/2990730-7d8be6ebc4c7c95b.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240',
  ),
  Car(
    name: '蘭博基尼Aventador',
    imageUrl:
    'https://upload-images.jianshu.io/upload_images/2990730-e3bfd824f30afaac?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240',
  ),
  Car(
    name: '法拉利Enzo',
    imageUrl:
    'https://upload-images.jianshu.io/upload_images/2990730-a1d64cf5da2d9d99?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240',
  ),
  Car(
    name: 'Zenvo ST1',
    imageUrl:
    'https://upload-images.jianshu.io/upload_images/2990730-bf883b46690f93ce?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240',
  ),
  Car(
    name: '邁凱倫F1',
    imageUrl:
    'https://upload-images.jianshu.io/upload_images/2990730-5a7b5550a19b8342?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240',
  ),
  Car(
    name: '薩林S7',
    imageUrl:
    'https://upload-images.jianshu.io/upload_images/2990730-2e128d18144ad5b8?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240',
  ),
  Car(
    name: '科尼賽克CCR',
    imageUrl:
    'https://upload-images.jianshu.io/upload_images/2990730-01ced8f6f95219ec?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240',
  ),
  Car(
    name: '布加迪Chiron',
    imageUrl:
    'https://upload-images.jianshu.io/upload_images/2990730-7fc8359eb61adac0?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240',
  ),
  Car(
    name: '軒尼詩Venom GT',
    imageUrl:
    'https://upload-images.jianshu.io/upload_images/2990730-d332bf510d61bbc2.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240',
  ),
  Car(
    name: '西貝爾Tuatara',
    imageUrl:
    'https://upload-images.jianshu.io/upload_images/2990730-3dd9a70b25ae6bc9?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240',
  )
];
複製程式碼

然後回到main.dart檔案新建一個Home類,用來存放我們ListView相關程式碼,和Xcode一樣Android Studio同樣有程式碼塊功能,直接輸入stl就會出現提示,回車就會生成StatelessWidget類相關程式碼。我們將Scaffold相關的程式碼挪到Home中來。 image.png

接下來就是正式開始使用ListView了,ListView跟其他一般的類不太一樣,它的初始化需要呼叫build方法,並且傳入兩個引數,一個是itemCount,一個是itemBuilder,有點類似我們UITableView的cellForRow方法,只不過我們UITableView使用的是代理的設計,而這裡的ListView使用的程式碼塊回撥的設計。

這裡說一個Android Studio的比Xcode好用的地方,如圖的itemCount使用了cars.length但是提示cars報錯,是因為沒有匯入car.dart檔案,給了個小紅燈泡。這個時候,我們游標移動到Car類上,然後使用option + 回車會彈出一個選單,再按一次回車就可以匯入我們的car.dart檔案了 image.png

itemBuilder屬性就是一個程式碼塊,用來配置每個item的樣式,我們可以先統一返回一個Text文字看看效果。 image.png 顯示效果就是類似於tableView一樣的一行行的文字

8天讓iOS開發者上手Flutter之一:快速入門Flutter

接下來介紹一個類似於UIView的容器類Container,它跟UIView類似,可以設定一些顏色,間距,子控制元件之類的,我們來試一下,將Text改為Container,child屬性就是子控制元件的意思,再給child設定為Text,文字就是cars裡面的name,程式碼如下: image.png 再看一下顯示效果

8天讓iOS開發者上手Flutter之一:快速入門Flutter

那麼如果我們現在想要顯示圖片加文字的話應該怎麼做呢?這裡再介紹一個Column類,和前面介紹Center類類似,同樣是屬於佈局的類,Column表示上下的佈局,因為我們想把圖片和文字上下襬放,所以需要用到Column這個類。然後關於圖片的顯示,這裡我們先不講怎麼去網路請求,而是直接使用Image類提供的一個方法去載入網路圖片,程式碼如圖: image.png 顯示效果如圖:

8天讓iOS開發者上手Flutter之一:快速入門Flutter

這個時候,你應該也猜到了,如果挪動children裡面Text和Image和順序,會發現圖片和文字的順序就交換了,是不是很容易理解。如果想要調整圖片和文字之間的間距怎麼調呢,使用SizedBox類,傳一個height就可以調整間距了,也可以繼續使用Container,程式碼如下: image.png

如果覺得itemBuilder的程式碼太長,也可以將它的程式碼封裝到一個方法裡面,例如我這裡使用iOS中的_cellForRow來命名這個方法。使用下劃線的意義的是表示這是一個私有方法。 image.png

APP右上角會發現有一個debug圖示,這個圖示的顯示在MaterialApp類裡面有一個屬性可以控制顯示隱藏。 debugShowCheckedModeBanner: false

常用Widget介紹

在介紹常用Widget之前,我們想把剛剛寫的ListView相關程式碼,封裝到一個檔案內,這樣方便以後我們回頭學習。listView_demo程式碼如下: image.png 這個時候,main.dart檔案內的Home類的build方法裡,返回我們的ListViewDemo初始化方法就行了。

然後再新建一個新的base_widget檔案,用來存放我們將要介紹的基礎Widget程式碼。 image.png 可以在main.dart檔案中直接使用我的BaseWidgetDemo初始化方法,這樣我們就不需要再去main.dart檔案修改程式碼了。每介紹一個新Widget直接修改BaseWidgetDemo的build方法返回值為我們的自定義類xxxDemo()就好了 image.png

第一個介紹是Text

Text

image.png Text我們一開始講過了,這裡就再講一點關於字串相關的,如果需要拼接字串可以使用$符號,如果字串中有特殊符號,那就使用${}。其他Text常用的屬性,跟我們iOS中都差不太多,需要注意的是Text的樣式,是在style裡面設定的。下面看一下APP顯示的效果

8天讓iOS開發者上手Flutter之一:快速入門Flutter

RichText

RichText就是富文字,它的text屬性可以傳一個TextSpan的類,這個TextSpan類可以設定text文字,設定style樣式,還可以設定children子控制元件,這樣就可以無限加花樣拼接各種字串在一起,程式碼如下 image.png APP上顯示的效果:

8天讓iOS開發者上手Flutter之一:快速入門Flutter

Container,Row

Container是個容器,Row是個用於佈局的類,跟Column,Center類似,根據程式碼檢視一下APP的顯示,就能大概明白意思了,程式碼如下: image.png APP顯示如下:

8天讓iOS開發者上手Flutter之一:快速入門Flutter

總結

今天介紹了Flutter裡面的許多的基礎Widget,有用於佈局的Center,Row,Column...有用於顯示文字的Text,RichText,TextSpan...有列表展示ListView,有基礎架構Scaffold,MaterialApp類,雖然東西有點多,但基本還沒有什麼難以理解的內容

相關文章