好啦~
这一天总是要来的
帮大家摘要一下
⚠️⚠️⚠️就是跟以前不一样的⚠️⚠️⚠️
☘️☘️☘️就是类似的或替代品☘️☘️☘️
- 可以选择用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 |
- children方式建立的ListView其TextField上的资料还是会跑掉
- 用ExpansionTile就可以做到folding效果
- 直接帮你算好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
- Flutter内建的
HttpClient
功能比较阳春, POST好像只支援application/json
- 完整一点的可以使用官方出的套件
http
- 或是第三方的Dio
![][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
- 要用Google Maps要先去CGP上面申请API Key
- 有提供my location button
- 要注意要求定位权限的时机要晚一点, 才不会卡在过场动画
- 体验
Zonble
大大有趣的side project
- 详细介绍可以看看他本人写的这篇Medium
结语
- 超级推荐《Flutter实战》这本电子书
又详细又丰富
-
手机跨平台讨论群(LINE)
- 对Android有兴趣的朋友可以右转iOS Developer Learning Android
- 官网简中版有中英对照
- Flutter写起来真的爽度满高的
感觉code都轻量化了
不用在那边拉来拉去了
边写边hot reload也很方便
- 不过要用在正式产品上还是会怕怕的, 尤其是金流/影音类
- 可是要是团队要推, 我会很乐意使用
- 万物皆Widget
- Widget真的超多种的(300多种)
不过也代表很多东西不用自己刻了
- 超容易写出波动拳的
可以参考一下这篇看看人家推荐怎麽写
- 要加;号结尾喔~
- Cupertino就是iOS风格的意思
- 使用declarative(声明式) UI
-
FWW - Google每周一分钟介绍一个Widget
- Flutter有自己的套件网站
- 有一些部分(像是页面跳转)会根据不同的平台自动转换行为
- 关於Layout我感觉:以前像是决定要把View放在哪里, 现在像是要把画布分割区块⚠️⚠️⚠️
- enum竟然不能直接用 .xxx 赋值⚠️⚠️⚠️
- Widget本身没有backgroundColor属性
- Text不是String是UILable⚠️⚠️⚠️
- 跟js一样使用async/await
- 推荐这个开源的App
- 推荐老孟的Widget大全
- 今年的iPlayground研讨会,小弟有幸分享上台「
iOS、Android、Flutter超级比一比
」主题
有兴趣的可以参考一下