2019年9月26日 星期四

Flutter 基礎, 掌握首要關鍵

1. StatelessWidget
2. StatefulWidget
3. InheritedWidget
4. StreamController
5. mixin
6. StreamBuilder 與 FutureBuilder
以上觀念了解透徹後, 稍俱 Javascript 觀念, 轉成 dart 的語法與運作邏輯, 就能得心應手.
只要跟時間相關, 會活動的部件就要繼承 extends StatefulWidget, 活動部件透過方法 setState((){}) 要求系統將部件重建, 至於靜態部件繼承 extends StatelessWidget, 若要重建, 只能透過活動式部件間接去重建一個新的, 當然前提是此部件必須是活動部件的下層部件, 因此部件之間有著上下階層關係,當上層部件重建時,下層部件就會跟進. 因此部件的佈屬方式與運作效能息息相關.一個部件當有需要時才重建, 是一個 Flutter 經典程式所需奉為圭臬的首要任務.部件透過建構式帶進參數去客製化只能單向往下溝通. 跨階層的溝通, 簡單的可經由 InheritedWidget 把參數往下遞延至子部件, 或是應用類型內的整體變數相互溝通, 複雜一點的, 可透過 StreamController 建構出管道(stream pipe)相互交流, StreamController( ) 的 stream 用來監聽 listen 輸入端進來的資料流(input stream), 而 sink 可以餵給輸出端加入 add 資料流(output stream). 把所有溝通管到全集中到 mixin 類型內,就能方便管理與運用, mixin 是一個不帶建構式的混合類型, 或者看成是方法與特性的集合營, 通常用在活動部件的狀態類型, (動態物件類型實際上也是一種靜態的類型, 因為特性常數必須 final), 當混入的各種特性都是常數時, 也許可以混進靜態類型內, 先繼承 extends 後, 接續 with 混合類型, 把方法與變數等各種特性混進來. 初始化物件可以放在部件的初始程序內, 靜態部件就直接放在建構式內, 活動式的部件除了可以放在建構式外, 有些時候要放在 initState 程序內, 部件最後是從 build 方法建構出來的, 因此 build 程式碼要愈短愈好.
備註:
1.  靜態物件與與靜態部件實際上是兩種不同的物件(instance),  同理, 活動物件與活動部件也是, 靜態物件或是活動物件(instance)是建構式產生的,  但部件(instance)確是 Flutter 透過物件內方法 built 建構出來的.
2. 靜態物件與靜態部件同在一個類型裏面, 因此特性或方法可以分享給部件:
class   My0Widget   extends   StatelessWidget  {  // 靜態物件類型, 繼承自靜態類型
       final value = 0;  // 常數必須 final , 讓靜態部件分享
      @override build(BuildContext   context)  => Text('Hello0') // 靜態部件的建構程序
}
3. 活動部件狀態變數位於活動狀態類型內, 與活動物件分屬不同的類型, 基本上, 活動物件類型內的特性都是常數(否則編譯時會有警告訊息, 只有活動狀態的物件可以是變數), 活動部件透過 widget. 可以取得活動物件內的特性, 但活動物件要反向取得活動部件的狀態, 還需要用點技巧才能取得:
imoprt 'dart:async';
import 'package:flutter/material.dart';
class   MyWidget   extends   StatefulWidget  { // 活動物件類型, 繼承自活動類型
      final  value = 0 ;     //特性常數(value) 必須 final, 活動部件透過  widget.特性常數  取值
      final  _MyState   myWidget; // 如有需要, 透過  .myWidget.狀態變數   間接取得
      static  MyWidget   singleton;  // 宣告一次性靜態共享物件, 實體是位於整體區域
      MyWidget._(this.myWidget);// 用帶名建構式, 初始化部件狀態 myWidget
      factory MyWidget( ){ // 用工廠建構式, 一次性初始化 singleton 與 _myWidget
           if( singleton == null )   singleton = MyWidget._(_MyState( )); // 初始化的活動物件
           return singleton; // 回傳靜態共享物件(instance)
      }
      @override createState( )  =>  myWidget; // 直接回傳部件狀態
}
_MyState   extends   State<MyWidget> { // 活動部件狀態類型繼承自活動狀態類型
     int   myState = 0;     // 狀態變數, 可以更新
     void rebuild(int _)  => setState(  ( ) =>  myState=_ ); // 改變狀態並呼叫部件重建的程序
    @override void initState( ) {
          Timer.periodic(Duration(seconds: 1),(_) => rebuild( myState+1) );//定時器更新狀態
     } // 活動部件的初始化程序
    @override build(BuildContext   context)  =>
      Text('Hi: myState=$myState, value=${widget.value}') ; // 活動部件的建構程序
}
// void main( ) {  print(  MyWidget( ).myWidget.myState  );   }

沒有留言:

張貼留言

使用 pcie 轉接器連接 nvme SSD

之前 AM4 主機板使用 pcie ssd, 但主機板故障了沒辦法上網, 只好翻出以前買的 FM2 舊主機板, 想辦法讓老主機復活, 但舊主機板沒有 nvme 的界面, 因此上網買了 pcie 轉接器用來連接 nvme ssd, 遺憾的是 grub2 bootloader 無法識...