☘️☘️☘️就是類似的或替代品☘️☘️☘️
- 就做個開場
- 然後介紹了一些學習資源
- 可以選擇用AS或VSCode
- 要自己下載SDK
⚠️ ⚠️ ⚠️ - 環境建立的詳細步驟
- 從AS就可以執行iOS模擬器了
- 就算是接實機也可以hot reload
⚠️ ⚠️ ⚠️
- Flutter專案裡還是有iOS跟Android資料夾
- 所以換icon基本上還是跟以前一樣的方法
- 當然你想要兩個平台用不一樣的icon也可以
- 也可以用flutter_launcher_icons方便替換
- iOS還是用LaunchScreen.storyboard☘️☘️☘️
- Android有分: launch screens(啟動頁):等待Android初始化 splash screens(閃屏頁):等待Dart初始化
- Flutter裡的世界裡什麼都是Widget 就先把它當成UIView吧☘️☘️☘️
- 有分StatelessWidget 跟 StatefulWidget 盡量少用StatefulWidget 除非會根據User或API改變的畫面
- 跟ViewController比較像的東西應該算是Scaffold☘️☘️☘️
- Flutter畫面不能用拉的
⚠️ ⚠️ ⚠️ - 有一些部分(像是頁面跳轉)會根據不同的平台自動轉換行為
- subview現在叫child/children☘️☘️☘️
- 跳頁的語法也滿像的
Navigator.push
- 關於Layout我感覺:以前像是決定要把View放在哪裏, 現在像是要把畫布分割區塊
⚠️ ⚠️ ⚠️ - 很常用到Column/Row(就是UIStackView☘️☘️☘️)
- Row是水平排列, Column是垂直排列
- Expanded
只能
在Flex裡使用 - 要把物件重疊就用Stack
- 以前iOS沒有下面這些UI類別
⚠️ ⚠️ ⚠️ - Align讓子widget對齊特定位置(九宮格)
- Padding讓子widget留邊距
- DecoratedBox裝飾子widget, 背景色或實現一些以前要在UIView.layer陰影/邊線/圓角做的事☘️☘️☘️
- SizedBox指定子widget大小
- Container是綜合上述多功能的Widget, 有時候直接用Container省得改來改去
- Text不是String是UILable
⚠️ ⚠️ ⚠️ - Text預設會自動折行, 不用怕忘記改行數了
⚠️ ⚠️ ⚠️ - TextField要透過controller物件才能控制它
⚠️ ⚠️ ⚠️
Android | iOS | Flutter |
---|---|---|
TextView | UILabel | Text |
EditText | UITextField | TextField |
- 按鈕透過onPressed callback來處理點擊事件
- onPressed為null按鈕就會強制變成disable
- 以前我們在用的UIControl都可以在這裡找到
- Alert要自己呼叫Navigator.pop才會關掉
⚠️ ⚠️ ⚠️ - 使用async/await才能取得Alert的結果
Android | iOS | Flutter |
---|---|---|
Button | UIButton | RawMaterialButton |
Dialog | UIAlertController | AlertDialog |
- UIImageView就是Image, UIImage就是ImageProvider☘️☘️☘️
- 使用圖片路徑跟副檔名都要
⚠️ ⚠️ ⚠️ - 內建讀取網路圖片功能
⚠️ ⚠️ ⚠️
Android | iOS | Flutter |
---|---|---|
ImageView | UIImageView | Image |
Bitmap | UIImage | ImageProvider |
ScaleType | UIViewContentMode | BoxFit |
- 注意showBottomSheet跟showModalBottomSheet是兩個不一樣的方法
Android | iOS | Flutter(Material) | Flutter(Cupertino) |
---|---|---|---|
Spinner | UIPickerView | showBottomSheet | CupertinoActionSheet |
DatePickerDialog | UIDatePicker | showDatePicker/showTimePicker | CupertinoDatePicker |
- TableView叫List☘️☘️☘️
- cell叫ListTile☘️☘️☘️
- 可以橫的
⚠️ ⚠️ ⚠️ - 也是要靠scrollController
- 有children(一次全建) 跟 builder(要顯示才建立)兩種建立方式
Android | iOS | Flutter |
---|---|---|
ListView | UITableView static cell | ListView use children |
RecycleView | UITableView dynamic cell | ListView.builder |
- 沒有section的概念
⚠️ ⚠️ ⚠️ - 置頂header使用sticky_headers套件
- children方式建立的ListView其TextField上的資料還是會跑掉
- 用ExpansionTile就可以做到folding效果
- 要做多選會用CheckboxListTile
- 側滑選項的話使用flutter_slidable
- 簡單提示訊息可以用SnackBar
- 直接幫你算好cell大小(爽爽的)
⚠️ ⚠️ ⚠️ - 但是不能paging scroll
⚠️ ⚠️ ⚠️
Android | iOS | Flutter |
---|---|---|
RecycleView(set GridLayoutManager) | UICollectionView | GridView |
- CustomScrollView就像CompositionalLayout☘️☘️☘️
- CustomScrollView裡面一定要用Sliver Widget
- CupertinoSliverRefreshControl就是在CustomScrollView使用
- BottomNavigationBar這個是TabBar☘️☘️☘️
- TabController這個不是TabBar...在iOS我不知道叫什麼, 就是那個可以用手勢換頁的
- BottomNavigationBar有分fixed 跟 shifting兩種Type
- 注意BottomNavigation超過三個就會轉成shifting
- BottomNavigation的換頁必須自己管理
Android | iOS | Flutter |
---|---|---|
BottomNavigationView | UITabBarController | BottomNavigationBar |
TabbedActivity | 看套件叫什麼它就叫什麼 | TabController |
- 唔...這天沒什麼重點XD, 就介紹一下怎麼轉Model跟打API
![][https://i.imgur.com/lCg6cWh.gif]
- Widget生命週期跟iOS/Android不太一樣, 沒有will/did相關的
- App生命週期要widget透過WidgetsBindingObserver自己監聽
iOS | Android | Flutter |
---|---|---|
init | onCreate | createState |
viewDidLoad | initState | |
viewWillAppear | onStart | 這個沒有真的滿傷的 |
viewDidLayoutSubviews | build | |
viewDidAppear | onResume | |
viewWillDisappear | onPause | |
viewDidDisappear | onStop | |
removeFromSuperview | deactivate | |
deinit | onDestroy | dispose |
WillEnterForeground | onRestart | |
DidBecomeActive | onStart | resumed |
WillResignActive | onPause | 這個沒有對金融業也滿傷的 |
DidEnterBackground | onStop | paused |
- UI樹一層包一層, 若底層的widget若想取得上層的state會很麻煩
- InheritedWidget讓底層widget可以方便取得上層的state
- 類似Singleton的作用☘️☘️☘️
- InheritedWidget更新了就會呼叫didChangeDependencies
- 就是進階版的InheritedWidget套件
- 可以做到以前NotificationCenter的效果☘️☘️☘️
- 如果要做到push到2ndVC時TabBar還在 就要Scaffold/TabBar/TabView整套換成Cupertino
- 如果要做到push到2ndVC時點TabBarItem可以popToRootVC
就要用navigatorKey去找到navigator再去
popUntil
- 也是類似NotificationCenter☘️☘️☘️
- 只是現在方向由下往上
- 畫這個金字塔比實作Notification麻煩XD
- 要另外裝image_picker
- 取得path之後, 透過path拿到File, 再用Image.file顯示
- SharedPreferences就是UserDefault☘️☘️☘️
- url_launcher就像openURL☘️☘️☘️
- 不過開網頁不是外開Safari了, 而是使用SFSafariViewController
⚠️ ⚠️ ⚠️
- 多圖詳細設定步驟
- 現在憑證都用.p8了
- 使用local_auth
- 不會拿到拒絕原因(LAError)
⚠️ ⚠️ ⚠️
- 要用Google Maps要先去CGP上面申請API Key
- 有提供my location button
- 要注意要求定位權限的時機要晚一點, 才不會卡在過場動畫
- 體驗
Zonble
大大有趣的side project - 詳細介紹可以看看他本人寫的這篇Medium