文檔地址
- https://flutter.dev
- https://dart.dev
- https://docs.flutter.dev/community/china
- https://flutter.cn
- https://pub.dev
- https://book.flutterchina.club
- https://mp.weixin.qq.com/mp/appmsgalbum?action=getalbum&album_id=1566028536430247937&__biz=Mzg5MDAzNzkwNA==#wechat_redirect
1诅需、下載安裝Flutter SDK:
- 官方下載地址:https://docs.flutter.dev/development/tools/sdk/releases?tab=macos
- Github下載地址:https://github.com/flutter/flutter
2杰标、設(shè)置Flutter鏡像源、環(huán)境變量:
- export PUB_HOSTED_URL=https://pub.flutter-io.cn
- export FLUTTER_STORAGE_BASE_URL=https://storage.flutter-io.cn
- export PATH=$PWD/flutter/bin:$PATH
3怀樟、刷新環(huán)境變量鸭巴、驗(yàn)證環(huán)境變量吗货、創(chuàng)建Flutter應(yīng)用:
- source ~/.bash_profile
- flutter --version
- flutter create app_name
4字逗、常用命令、插件(flutter醒陆、dart瀑构、code runner)
flutter --version
flutter doctor
flutter create msb_app
flutter run
flutter run --no-sound-null-safety
flutter devices
open -a Simulator
dart --version
which dart
flutter pub get
5、注意
- 常用布局:
1刨摩、row/column占據(jù)父組件寬度是整個(gè)行寺晌,主軸上的大小默認(rèn)為能占多大就占多大,即:mainAxisSize: MainAxisSize.max码邻,如果想要主軸寬度包裹內(nèi)容則設(shè)置mainAxisSize: MainAxisSize.min折剃。交叉軸默認(rèn)包裹內(nèi)容,如果想要row交叉軸高度拉伸到最大空間,將所有子widget交叉軸的高度拉伸到最大則crossAxisAlignment: CrossAxisAlignment.stretch;
2像屋、stack默認(rèn)大小包裹內(nèi)容怕犁,alignment:從什么位置開始布局所有子組件,fit:expand將子元素拉伸盡可能大己莺,overflow:超出部分如何處理奏甫;
3、listview/gridview 查看源碼是只要不是繼承于widget那么就是一個(gè)普通的類凌受,繼續(xù)查看父類阵子,直到看到是繼承于widget;一旦看到widget就去看build方法胜蛉,因?yàn)閎uild方法才是真正返回所使用的東西挠进,然后查看build返回的對(duì)象是否繼承與RenderObjectWidget色乾,如果是那么就是真正渲染的的東西,flutter引擎渲染Render樹里面相對(duì)應(yīng)的RenderObjectWidget领突,最終代碼真正的渲染到屏幕里面暖璧,listview/gridview本質(zhì)都會(huì)調(diào)用buildSlivers方法,slivers才是真正可以滾動(dòng)的東西君旦,buildSlivers方法是個(gè)抽象方法澎办,需要ScrollView的子類去實(shí)現(xiàn),子類有BoxScrollView和CustomScrollView金砍,BoxScrollView類中buildSlivers方法有個(gè)buildChildLayout抽象方法局蚀,需要子類listview/gridview去實(shí)現(xiàn),listview中在buildChildLayout實(shí)現(xiàn)方法中創(chuàng)建返回了SliverFixedExtentList或者SliverList恕稠,gridview中在buildChildLayout實(shí)現(xiàn)方法中創(chuàng)建返回了SliverGrid琅绅。
- 常用
1、SizeBox(height:8);設(shè)置間隔
2谱俭、Divider(height: 1);分割線
3奉件、ClipRect();將 child 剪裁為給定的矩形大小
4宵蛀、ClipRRect();將 child 剪裁為圓角矩形
5昆著、ClipOval();如果 child 為正方形時(shí)剪裁之后是圓形,如果 child 為矩形時(shí)术陶,剪裁之后為橢圓形
6凑懂、ClipPath();將 child 按照給定的路徑進(jìn)行裁剪
7、CustomClipper();并不是一個(gè)widget梧宫,但是使用CustomClipper可以繪制出任何我們想要的形狀
8接谨、Text.rich();富文本,可換行
9、double.infinity;盡可能寬的
10塘匣、identical(a,b);比較兩個(gè)對(duì)象是否是同一個(gè)對(duì)象
11脓豪、設(shè)置Row內(nèi)部組件相同的高度,就在Row外部包裝一層IntrinsicHeight()
12忌卤、封裝打印日志區(qū)分debug模式打印release模式不打印<文件扫夜、行號(hào)、列號(hào)驰徊、內(nèi)容>
13笤闯、UniqueKey();創(chuàng)建唯一隨機(jī)數(shù),其本質(zhì)是用當(dāng)前的對(duì)象生成哈希code棍厂;
14颗味、默認(rèn)情況下只要是創(chuàng)建widget,它都可以綁定一個(gè)key;
15牺弹、在父widget里面去拿子widget某個(gè)對(duì)象的屬性或者方法就是通過globalKey進(jìn)行獲绕致怼时呀;屬于組件之間的相互引用;
16晶默、element對(duì)兩個(gè)東西有引用即為有兩個(gè)屬性分別是_widget退唠、_renderObject; _widget會(huì)保存一個(gè)key,如果element._widget和widget樹中的widget類型相同并且key也相同的話,那么完全沒有必要重新創(chuàng)建element荤胁,那么也完全沒必要去重新創(chuàng)建renderObject瞧预,只是更新element/renderObject里面的屬性即可,但是widget樹中的widget是重新創(chuàng)建的,這樣最大的好處是用最小的開銷來更新renderObject仅政,flutter引擎下一次來解析renderObject的時(shí)候只需要發(fā)現(xiàn)renderObject屬性發(fā)生改變了垢油,只需要用最小的開銷把這個(gè)renderObject重新做一個(gè)渲染就可以了,所以element樹層類似于一個(gè)虛擬DOM圆丹,主要就是看一下當(dāng)前頁面的改變滩愁,然后用我們最小的開銷做一個(gè)對(duì)比,然后用最小的開銷來更新renderObject辫封;
17硝枉、Widget描述和配置子樹的樣子,Element是一個(gè)Widget的實(shí)例倦微,而Element實(shí)際去配置在Element樹中特定的位置妻味,RenderObject渲染樹上的一個(gè)對(duì)象,RenderObject層是渲染庫的核心欣福。
18责球、組件Widget:不會(huì)生成RenderObject,例如Container->StatelessWidget-Widget拓劝;渲染W(wǎng)idget:會(huì)生成RenderObject雏逾,例如Padding->SingleChildRenderObjectWidget->RenderObjectWidget<核心抽象方法createRenderObject()>->Widget;Widget里面抽象方法Element createElement();所有的Widget都會(huì)創(chuàng)建一個(gè)對(duì)應(yīng)的Element對(duì)象郑临;
StatelessElement;
StatefulElement; ->_state引用栖博;而_state對(duì)Widget有引用;
19厢洞、Widget常見子類有StatelessWidget仇让、StatefulWidget、RenderObjectWidget犀变;RenderObjectWidget里面有個(gè)核心抽象方法createRenderObjectWidget()妹孙,該抽象方法被它的子類的子類所實(shí)現(xiàn)創(chuàng)建RenderObject對(duì)象,例如Padding類實(shí)現(xiàn)了createRenderObjectWidget()方法获枝,總之是RenderObjectWidget類里面實(shí)現(xiàn)了createRenderObjectWidget()方法蠢正,創(chuàng)建了RenderObject對(duì)象,所以我們知道他們之間存在這樣的關(guān)系省店;
20嚣崭、
1)笨触、自己寫Widget;
2)雹舀、某些Widget中會(huì)創(chuàng)建RenderObject芦劣;
3)、每一個(gè)Widget都會(huì)創(chuàng)建一個(gè)Element對(duì)象,會(huì)調(diào)用mount方法说榆;
4)虚吟、Element類里面有個(gè)mount方法,當(dāng)Element對(duì)象創(chuàng)建完成之后flutter引擎自己會(huì)去調(diào)用mount方法签财,mount方法里面會(huì)調(diào)用_firstBuild()方法<表示第一次構(gòu)建方法>串慰,_firstBuild()方法里面去調(diào)用rebuild()方法<表示重新構(gòu)建>,rebuild()方法里調(diào)用performRebuild()抽象方法唱蒸,去查看它的實(shí)現(xiàn)邦鲫,例如ComponentElement里面實(shí)現(xiàn)performRebuild()的方法中調(diào)用了方法build()會(huì)生成一個(gè)Widget即Widget built = build(),也就是說在Element里面調(diào)用了build()方法神汹,build()方法是一個(gè)抽象方法庆捺,去看它的實(shí)現(xiàn)例如StatelessElement里面的build()方法,即Widget = build() => widget.build(this);(例如1屁魏、ComponentElement執(zhí)行過程:mount方法->firstBuild->rebuild->performBuild->build->_widget.build(this)滔以,this就是當(dāng)前Element,所以BuildContext就是Widget對(duì)應(yīng)的Element對(duì)象蚁堤,主要作用是執(zhí)行build方法去構(gòu)建更多的東西醉者。2、RenderObjectElement執(zhí)行過程:mount方法 -> _renderObject = widget.createRenderObject會(huì)被掛載到RenderObjectElement一個(gè)屬性)披诗,主要作用是創(chuàng)建RenderObject;這既是1和2兩者的最主要的區(qū)別。3立磁、stateFulWidgetElement繼承自ComponentElement呈队,所以父類有點(diǎn)東西子類都有,在stateFulWidgetElement構(gòu)造器的初始化列表里面調(diào)用了_state = widget.createState()唱歧,_state._widget = widget)宪摧。Element對(duì)_widget、_randerObject颅崩、_state都有引用;
總結(jié):每一個(gè)Widget都會(huì)創(chuàng)建一個(gè)Element對(duì)象几于,會(huì)調(diào)用element里面的一個(gè)mount方法,mount方法經(jīng)過一列方法調(diào)用方法之后會(huì)調(diào)用Widget的build(BuildContext context)方法沿后,Element會(huì)用屬性_widget來引用剛創(chuàng)建出來的Widget沿彭;如果Element是一個(gè)RunderElement,它主要做得事情是會(huì)創(chuàng)建一個(gè)RunderObject尖滚,RunderElement會(huì)用屬性_runderObject引用剛創(chuàng)建出來的這個(gè)RunderObject喉刘;如果Element是一個(gè)stateFulElement那么會(huì)使用_state = widget.createState()瞧柔,_state._widget = widget。
21睦裳、FittedBox()造锅,自動(dòng)適當(dāng)放大縮小,放置組件越界報(bào)錯(cuò);占據(jù)盡可能大的寬度廉邑;跟圖片widget使用有點(diǎn)類似哥蔚;
22、IgnorePointer();指針忽略蛛蒙;
23肺素、EventBus:時(shí)間總線;國外有個(gè)人寫的一個(gè)三方event_bus;
24宇驾、路由管理:所有的頁面在進(jìn)行路由跳轉(zhuǎn)之前必須把頁面進(jìn)行包裝倍靡,包裝到路由里面,包裹成一個(gè)路由對(duì)象课舍,flutter的navigatater才會(huì)幫我們管理路由塌西;MaterialPageRoute:用的最多的路由包裹類;Navigator():負(fù)責(zé)管理所有的Route的Widget,通過一個(gè)數(shù)據(jù)結(jié)構(gòu)Stack棧結(jié)構(gòu)來進(jìn)行管理的筝尾;
25捡需、WillPopScope();
26、flutter重寫操作符
27筹淫、.of什么意思站辉?
28、
- https://javiercbk.github.io/json_to_dart/
-
https://app.quicktype.io
29损姜、http://123.207.32.32:8001/api/meal
30饰剥、ListView在父容器里面占據(jù)盡可能大的空間、Column希望所有的子widget有一個(gè)明確的高度摧阅;注意容易報(bào)hasSize錯(cuò)誤汰蓉;設(shè)置ListView的屬性shrinkWrap:true;physics:NeverScrollableScrollPhysics;padding:EdgeInsets.zero;
31、共享狀態(tài)管理
32棒卷、生命周期 - StatelessWidget
1)構(gòu)造函數(shù)
2)build - StatefulWidget
1)構(gòu)造函數(shù)
2)initState
3)didChangeDependencies
4)build
5)dispose
父組件不設(shè)置寬度顾孽,則寬度是內(nèi)容寬度,如果內(nèi)容寬度超過屏幕測(cè)上色欄桿報(bào)錯(cuò)比规,應(yīng)在父組件外包裹一層Expened()組件若厚;
如何配置類似iOS的pch文件