Flutter知識(shí)點(diǎn)記錄

1、const 變量是一個(gè)編譯時(shí)常量,final變量在第一次使用時(shí)被初始化。被final或者const修飾的變量,變量類型可以省略。
2、Dart函數(shù)聲明如果沒有顯式聲明返回值類型時(shí)會(huì)默認(rèn)當(dāng)做dynamic處理。
3、用[]標(biāo)記為可選的位置參數(shù)(參數(shù)位置對(duì)應(yīng)),使用{paramName},用于指定命名參數(shù)(paramName: value)。
4、一個(gè)Future只會(huì)對(duì)應(yīng)一個(gè)結(jié)果,要么成功,要么失敗。
5、有些時(shí)候,我們需要等待多個(gè)異步任務(wù)都執(zhí)行結(jié)束后才進(jìn)行一些操作,比如我們有一個(gè)界面,需要先分別從兩個(gè)網(wǎng)絡(luò)接口獲取數(shù)據(jù),獲取成功后,我們需要將兩個(gè)接口數(shù)據(jù)進(jìn)行特定的處理后再顯示到UI界面上,應(yīng)該怎么做?答案是Future.wait,它接受一個(gè)Future數(shù)組參數(shù),只有數(shù)組中所有Future都執(zhí)行成功后,才會(huì)觸發(fā)then的成功回調(diào),只要有一個(gè)Future執(zhí)行失敗,就會(huì)觸發(fā)錯(cuò)誤回調(diào)。

Future.wait([
  // 2秒后返回結(jié)果  
  Future.delayed(new Duration(seconds: 2), () {
    return "hello";
  }),
  // 4秒后返回結(jié)果  
  Future.delayed(new Duration(seconds: 4), () {
    return " world";
  })
]).then((results){
  print(results[0]+results[1]);
}).catchError((e){
  print(e);
});

6、Stream 也是用于接收異步事件數(shù)據(jù),和Future 不同的是,它可以接收多個(gè)異步操作的結(jié)果(成功或失?。?/p>

  // 1秒后返回結(jié)果
  Future.delayed(new Duration(seconds: 1), () {
    return "hello 1";
  }),
  // 拋出一個(gè)異常
  Future.delayed(new Duration(seconds: 2),(){
    throw AssertionError("Error");
  }),
  // 3秒后返回結(jié)果
  Future.delayed(new Duration(seconds: 3), () {
    return "hello 3";
  })
]).listen((data){
   print(data);
}, onError: (e){
   print(e.message);
},onDone: (){

});

上面的代碼依次會(huì)輸出:

I/flutter (17666): hello 1
I/flutter (17666): Error
I/flutter (17666): hello 3

7、Navigator.push(BuildContext context, Route route)等價(jià)于Navigator.of(context).push(Route route)
8、頁(yè)面?zhèn)髦?/p>

      onPressed: () => Navigator.pop(context, "我是返回值"),

      onPressed: () async {
          // 打開`TipRoute`,并等待返回結(jié)果
          var result = await Navigator.push(
            context,
            MaterialPageRoute(
              builder: (context) {
                return TipRoute(
                  // 路由參數(shù)
                  text: "我是提示xxxx",
                );
              },
            ),
          );
          //輸出`TipRoute`路由返回結(jié)果
          print("路由返回值: $result");

9、獲取路由參數(shù)var args=ModalRoute.of(context).settings.arguments;在打開路由時(shí)傳遞參數(shù)Navigator.of(context).pushNamed("new_page", arguments: "hi")
10、onGenerateRoute,onGenerateRoute只會(huì)對(duì)命名路由生效。

MaterialApp(
  ... //省略無關(guān)代碼
  onGenerateRoute:(RouteSettings settings){
      return MaterialPageRoute(builder: (context){
           String routeName = settings.name;
       // 如果訪問的路由頁(yè)需要登錄,但當(dāng)前未登錄,則直接返回登錄頁(yè)路由,
       // 引導(dǎo)用戶登錄;其它情況則正常打開路由。
          
     }
   );
  }
);

11、
image.png

12、fontSize可以精確指定字體大小,而textScaleFactor只能通過縮放比例來控制。textScaleFactor主要是用于系統(tǒng)字體大小設(shè)置改變時(shí)對(duì)Flutter應(yīng)用字體進(jìn)行全局調(diào)整,而fontSize通常用于單個(gè)文本,字體大小不會(huì)跟隨系統(tǒng)字體大小變化。
13、Checkbox有一個(gè)屬性tristate ,表示是否為三態(tài),其默認(rèn)值為false ,這時(shí)Checkbox有兩種狀態(tài)即“選中”和“不選中”,對(duì)應(yīng)的value值為true和false 。如果tristate值為true時(shí),value的值會(huì)增加一個(gè)狀態(tài)null
14、通過ConstrainedBox來確保Stack占滿屏幕

ConstrainedBox(
  constraints: BoxConstraints.expand(),
  child: Stack(
    alignment:Alignment.center , //指定未定位或部分定位widget的對(duì)齊方式
    children: <Widget>[
      Container(child: Text("Hello world",style: TextStyle(color: Colors.white)),
        color: Colors.red,
      ),
      Positioned(
        left: 18.0,
        child: Text("I am Jack"),
      ),
      Positioned(
        top: 18.0,
        child: Text("Your friend"),
      )        
    ],
  ),
);

15、widthFactor和heightFactor,縮放因子,會(huì)分別乘以子元素的寬、高,最終的結(jié)果就是組件的寬高,如果值為null,則組件的寬高將會(huì)占用盡可能多的空間。
16、FractionalOffset 繼承自 Alignment,它和 Alignment唯一的區(qū)別就是坐標(biāo)原點(diǎn)不同;FractionalOffset 的坐標(biāo)原點(diǎn)為矩形的左側(cè)頂點(diǎn),Alignment Widget會(huì)以矩形的中心點(diǎn)作為坐標(biāo)原點(diǎn)。
17、ConstrainedBox只限制了最小高度,并未限制最大高度,UnconstrainedBox不會(huì)對(duì)子組件產(chǎn)生任何限制,它允許其子組件按照其本身大小繪制。一般情況下,我們會(huì)很少直接使用此組件,但在"去除"多重限制的時(shí)候也許會(huì)有幫助。
19、RotatedBox和Transform.rotate功能相似,它們都可以對(duì)子組件進(jìn)行旋轉(zhuǎn)變換,但是有一點(diǎn)不同:RotatedBox的變換是在layout階段,會(huì)影響在子組件的位置和大小。
20、MediaQuery.removePadding可以移除Drawer默認(rèn)的一些留白(比如Drawer默認(rèn)頂部會(huì)留和手機(jī)狀態(tài)欄等高的留白)
21、ClipRRect將子組件剪裁為圓角矩形,ClipRect剪裁子組件到實(shí)際占用的矩形大?。ㄒ绯霾糠旨舨茫?br> 22、一個(gè)ListView的顯示區(qū)域高度是800像素,雖然其列表項(xiàng)總高度可能遠(yuǎn)遠(yuǎn)超過800像素,但是其ViewPort仍然是800像素。
23、通??蓾L動(dòng)組件的子組件可能會(huì)非常多、占用的總高度也會(huì)非常大;如果要一次性將子組件全部構(gòu)建出將會(huì)非常昂貴!為此,F(xiàn)lutter中提出一個(gè)Sliver(中文為“薄片”的意思)概念,如果一個(gè)可滾動(dòng)組件支持Sliver模型,那么該滾動(dòng)可以將子組件分成好多個(gè)“薄片”(Sliver),只有當(dāng)Sliver出現(xiàn)在視口中時(shí)才會(huì)去構(gòu)建它,這種模型也稱為“基于Sliver的延遲構(gòu)建模型”??蓾L動(dòng)組件中有很多都支持基于Sliver的延遲構(gòu)建模型,如ListView、GridView,但是也有不支持該模型的,如SingleChildScrollView。
24、在ListView中,指定itemExtent比讓子組件自己決定自身長(zhǎng)度會(huì)更高效,這是因?yàn)橹付╥temExtent后,滾動(dòng)系統(tǒng)可以提前知道列表的長(zhǎng)度,而無需每次構(gòu)建子組件時(shí)都去再計(jì)算一下,尤其是在滾動(dòng)位置頻繁變化時(shí)。
25、PageStorage是一個(gè)用于保存頁(yè)面(路由)相關(guān)數(shù)據(jù)的組件,它并不會(huì)影響子樹的UI外觀,其實(shí),PageStorage是一個(gè)功能型組件,它擁有一個(gè)存儲(chǔ)桶(bucket),子樹中的Widget可以通過指定不同的PageStorageKey來存儲(chǔ)各自的數(shù)據(jù)或狀態(tài)。
26、Color類中提供了一個(gè)computeLuminance()方法,它可以返回一個(gè)[0-1]的一個(gè)值,數(shù)字越大顏色就越淺
27、

ThemeData({
  Brightness brightness, //深色還是淺色
  MaterialColor primarySwatch, //主題顏色樣本,見下面介紹
  Color primaryColor, //主色,決定導(dǎo)航欄顏色
  Color accentColor, //次級(jí)色,決定大多數(shù)Widget的顏色,如進(jìn)度條、開關(guān)等。
  Color cardColor, //卡片顏色
  Color dividerColor, //分割線顏色
  ButtonThemeData buttonTheme, //按鈕主題
  Color cursorColor, //輸入框光標(biāo)顏色
  Color dialogBackgroundColor,//對(duì)話框背景顏色
  String fontFamily, //文字字體
  TextTheme textTheme,// 字體主題,包括標(biāo)題、body等文字樣式
  IconThemeData iconTheme, // Icon的默認(rèn)樣式
  TargetPlatform platform, //指定平臺(tái),應(yīng)用特定平臺(tái)控件風(fēng)格
  ...
})

28、ConnectionState.active只在StreamBuilder中才會(huì)出現(xiàn)。
29、如果AlertDialog的內(nèi)容過長(zhǎng),內(nèi)容將會(huì)溢出,這在很多時(shí)候可能不是我們期望的,所以如果對(duì)話框內(nèi)容過長(zhǎng)時(shí),可以用SingleChildScrollView將內(nèi)容包裹起來。
30、一定要將StatefulBuilder和Builder理解透徹,因?yàn)樗鼈冊(cè)贔lutter中是非常實(shí)用的。
31、PointerEvent behavior : HitTestBehavior.deferToChild:默認(rèn)值,子組件會(huì)一個(gè)接一個(gè)的進(jìn)行命中測(cè)試,如果子組件中有測(cè)試通過的,則當(dāng)前組件通過;HitTestBehavior.opaque:當(dāng)前Widget的整個(gè)區(qū)域都是點(diǎn)擊區(qū)域;HitTestBehavior.translucent:當(dāng)點(diǎn)擊組件透明區(qū)域時(shí),可以對(duì)自身邊界內(nèi)及底部可視區(qū)域都進(jìn)行命中測(cè)試;
32、假如我們不想讓某個(gè)子樹響應(yīng)PointerEvent的話,我們可以使用IgnorePointer和AbsorbPointer,這兩個(gè)組件都能阻止子樹接收指針事件,不同之處在于AbsorbPointer本身會(huì)參與命中測(cè)試,而IgnorePointer本身不會(huì)參與,這就意味著AbsorbPointer本身是可以接收指針事件的(但其子樹不行),而IgnorePointer不可以。
33、使用GestureRecognizer后一定要調(diào)用其dispose()方法來釋放資源(主要是取消內(nèi)部的計(jì)時(shí)器)。
34、手勢(shì)沖突只是手勢(shì)級(jí)別的,而手勢(shì)是對(duì)原始指針的語(yǔ)義化的識(shí)別,所以在遇到復(fù)雜的沖突場(chǎng)景時(shí),都可以通過Listener直接識(shí)別原始指針事件來解決沖突。
35、Image(Image.asset)如果不定義fit,那么寬高最大只會(huì)是圖片本身的大小。
36、AnimatedSwitcher的新舊child,如果類型相同,則Key必須不相等。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容