Flutter 知識點總結(jié)

 MainAxisAlignment.spaceBetween
將主軸空白位置進(jìn)行均分,排列子元素,首尾子控件距邊緣沒有間隙
MainAxisAlignment.spaceAround
將主軸空白區(qū)域均分域那,使中間各個子控件間距相等,首尾子控件距邊緣間距為中間子控件間距的一半
MainAxisAlignment.spaceEvenly
將主軸空白區(qū)域均分邮偎,使各個子控件間距相等

flutter column row布局的列表自適應(yīng)寬高
mainAxisSize: MainAxisSize.min

通過runtimeType可以獲取當(dāng)前數(shù)據(jù)類型
var e = [12.5,13.1];
print('e 的類型是: ${e.runtimeType}'); // e 的類型是: List<double>

flutter column嵌套listview不能滾動,或者不顯示的問題

因為 listview水平視口的寬度是無限的喉磁。
在listview外面嵌套一個expanded,或者一個container就可以了棕叫,尺寸計算的問題幔荒,expande就是listview有多大就有多大,container就是container多大listview就有多大糊闽,可以滾動

 child: Row(
          children: <Widget>[
            Expanded(
              child: ListView.builder(
                shrinkWrap: true,
                scrollDirection: Axis.horizontal,
                physics: BouncingScrollPhysics(parent: AlwaysScrollableScrollPhysics()),
                itemCount: 120,
                itemBuilder: (context, index) => Padding(
                  padding: const EdgeInsets.all(8.0),
                  child: new Text('${index}'),
                ),
              ),
            ),
          ],
        ),

List 常見用法


   List<dynamic> topTitles = ['審批單', '機(jī)票列表', '客服'];
    //遍歷list
    for(var value intopTitles){
      print("---------<>---${value}");
    }
    topTitles.forEach((item) => {print(item)});


//遍歷得到一個新的List  用此方法 亦可動態(tài)加載Widget
   List<dynamic>   newList = topTitles.map((item) {
      return item + "111";
    }).toList();


//list的map方法不能獲取index  用Asmap  轉(zhuǎn)換成map 后
//動態(tài)加載Widget

        Row(
                children: topTitles
                    .asMap()
                    .keys
                    .map((index) => Expanded(
                          flex: 1,
                          child: Column(
                            children: <Widget>[Text(topTitles[index])],
                          ),
                        ))
                    .toList(),
              ),



Map


    //遍歷map
 mostCare.forEach((k, v) {
      // print(k + "==" + v.toString()); //類型不一樣的時候就toString()
    });



//map   key遍歷生成Widget
 Row(
                children: mostCare.keys.map((key) {
                  //  print('-----key--${key}');
                  return Expanded(
                    flex: 1,
                    child: Column(
                      children: <Widget>[Text(mostCare[key])],
                    ),
                  );
                }).toList(),
              ),

延遲

/*    //延遲3秒
    Future.delayed(Duration(seconds: 3), () {
     
    });*/

軟鍵盤彈出頂?shù)魞?nèi)容梳玫、防止鍵盤超出屏幕

研究了半天發(fā)現(xiàn)十分簡單,只需兩行代碼右犹。布局中最外層包裹一個SingleChildScrollView組件提澎,然后在Scaffold里增加一個屬性 resizeToAvoidBottomPadding: false,即刻解決鍵盤遮擋問題,
類似于 Android 中的 android:windowSoftInputMode=”adjustResize”念链,控制界面內(nèi)容 body 是否重新布局來避免底部被覆蓋了盼忌,比如當(dāng)鍵盤顯示的時候,重新布局避免被鍵盤蓋住內(nèi)容掂墓。默認(rèn)值為 true谦纱。

Flutter TextField 光標(biāo)和內(nèi)容不能對齊問題

添加該屬性
TextField(
    style: TextStyle(textBaseline: TextBaseline.alphabetic),
)

flutter中text設(shè)置overflow還是會超出屏幕解決方法

使用flex控件代替row控件,并且在文字外面包一層Expanded
君编,應(yīng)該是橫向row沒有確定寬度跨嘉,text根據(jù)內(nèi)容來撐開row,所以就會超出吃嘿,換成flex 使text最大寬度能占用剩下的所有寬度祠乃,所以達(dá)到最寬的時候就會顯示省略號。
這個錯誤就好像再column中使用listView一樣兑燥,會出現(xiàn)一個在無限高度的view中使用listView的錯誤,

屏幕適配原理

flutter_screenutil:

說一下適配方案, 比如我們設(shè)計師設(shè)計的UI是根據(jù)Iphone6來做的,我們知道 iPhone6的分辨率是750*1334(px)亮瓷、

又或者是根據(jù)hdpi的設(shè)備來設(shè)計的UI,我們知道hdpi的 Android設(shè)備是 (240 dpi),像素密度是1.5,即hdpi設(shè)備的分辨率寬度是320px, 總之,無論設(shè)計稿的單位是px,或者是dp,我們都能夠轉(zhuǎn)換成px.
那么我們?nèi)绻鶕?jù)px來適配,ios和 android 就都可以兼容了.
假設(shè),我們的設(shè)計稿手機(jī)是10801920 px.
設(shè)計稿上有一個540960 的組件, 即寬度和寬度是手機(jī)的一半. 如果我們直接寫的時候組件的尺寸這么定義,在其他尺寸的設(shè)備上未必是一半,或多,或少. 但是我們可以按比例來看,即我們要實現(xiàn)的寬度是實際設(shè)備的一半.
那么假設(shè)我們設(shè)備的寬度是deviceWidth和deviceHeight , 我們要寫的組件大小為: 寬:(540/1080)deviceWidth,高度: (960/1920)deviceHeight.
通過這個公式我們可以發(fā)現(xiàn),我們要寫的組件寬度就是設(shè)計稿上的尺寸width(deviceWdith/原型設(shè)備寬度).那么每次我們寫ui的時候,只要直接哪來設(shè)計稿的尺寸(deviceWdith/設(shè)備原型)寬度即可
原理就是先獲取,實際設(shè)備與原型設(shè)備的尺寸比例.

構(gòu)造方法

如果沒有自定義構(gòu)造方法,則會有個默認(rèn)構(gòu)造方法
如果存在自定義構(gòu)造方法 默認(rèn)構(gòu)造方法將失效
構(gòu)造方法不能重載

命名構(gòu)造方法
使用命名構(gòu)造方法 可以實現(xiàn)多個構(gòu)造方法
使用 類名.方法 的形式實現(xiàn)

class Person {
    string name
    int age
    final string sex
    /**
     * 這里 使用this的語法糖可以對final類型賦值
     * 但是寫在構(gòu)造方法中就不行了,因為執(zhí)行在構(gòu)造方法之前
     */
    Person (string name ,this.age ,this.sex) { // 第二種是語法糖,
        this.name = name
        print(age)
    }
}

var per = new Person('jack', 20)

---------------------------------------
命名構(gòu)造方法
class Person {
    string name
    int age
    final string sex

    Person (string name ,this.age ,this.sex) { // 第二種是語法糖,
        this.name = name
        print(age)
    }
    Person.withName(string name) {
        this.name = name
    }
}
<!-- 多個構(gòu)造方法 類似oc -->
new Person('jack', 12, 'man')
new Person.withName('marry')

混合 mixins (with)

除了繼承和接口實現(xiàn)之外,Dart 還提供了另一種機(jī)制來實現(xiàn)類的復(fù)用降瞳,即“混入”(Mixin)嘱支。通過混入,一個類里可以以非繼承的方式使用其他類中的變量與方法挣饥,效果正如你想象的那樣除师。

混合的對象是類
可以混合多個

生命周期

State 的生命周期可以分為 3 個階段。
State 初始化時會依次執(zhí)行 :構(gòu)造方法 -> initState -> didChangeDependencies -> build扔枫,隨后完成頁面渲染馍盟。
Widget 的狀態(tài)更新,主要由 3 個方法觸發(fā):setStState茧吊、didchangeDependencies 與 didUpdateWidget。
Widget 組件銷毀相對比較簡單八毯,系統(tǒng)會調(diào)用 deactivate 和 dispose 這兩個方法搓侄,來移除或銷毀組件。

Widget 渲染過程

  • Widget话速、是控件實現(xiàn)的基本邏輯單位讶踪,里面存儲的是有關(guān)視圖渲染的配置信息,包括布局泊交、渲染屬性乳讥、事件響應(yīng)信息等柱查。
  • Element :是 Widget 的一個實例化對象,它承載了視圖構(gòu)建的上下文數(shù)據(jù)云石,是連接結(jié)構(gòu)化的配置信息到完成最終渲染的橋梁唉工。
  • RenderObject 、主要負(fù)責(zé)實現(xiàn)視圖渲染的對象汹忠、通過控件樹中的每個控件創(chuàng)建不同類型的渲染對象淋硝,組成渲染對象樹。

Fluttter 將視圖樹的概念進(jìn)行了擴(kuò)展宽菜,把視圖數(shù)據(jù)的組織和渲染抽象為三部分谣膳,即 Widget,Element 和 RenderObject铅乡。
渲染對象樹在 Flutter 的展示過程分為四個階段继谚,即布局、繪制阵幸、合成和渲染花履。
布局和繪制在 RenderObject 中完成,F(xiàn)lutter 采用深度優(yōu)先機(jī)制遍歷渲染對象樹侨嘀,確定樹中各個對象的位置和尺寸臭挽,并把它們繪制到不同的圖層上,布局和繪制完成后咬腕,再交給 Skia進(jìn)行合成和渲

為什么需要增加中間的這層 Element 樹呢欢峰?直接由 Widget 命令 RenderObject 去干活兒不好嗎?

因為 Widget 具有不可變性涨共,但 Element 卻是可變的纽帖,實際上,Element 樹這一層將 Widget 樹的變化(類似 React 虛擬 DOM diff)做了抽象举反,可以只將真正需要修改的部分同步到真實的 RenderObject 樹中懊直,最大程度降低對真實渲染視圖的修改,提高渲染效率火鼻,而不是銷毀整個渲染視圖樹重建室囊。

合成和渲染

隨著頁面越來越復(fù)雜、Flutter 的渲染樹層級很多魁索,直接交付給渲染引擎進(jìn)行多圖層渲染融撞,可能會出現(xiàn)大量渲染內(nèi)容的重復(fù)繪制,所以還需要先進(jìn)行一次圖層合成粗蔚,即將所有的圖層根據(jù)大小尝偎、層級、透明度等規(guī)則計算出最終的顯示效果,將相同的圖層歸類合并致扯,簡化渲染樹肤寝,提高渲染效率,合并完成后抖僵,F(xiàn)lutter 會將幾何圖層數(shù)據(jù)交由 Skia 引擎加工成二維圖像數(shù)據(jù)鲤看,最終交由 GPU 進(jìn)行渲染,完成界面的展示裆针。

StatelessWidget與StatefulWidget區(qū)別

分別是組裝控件的容器
StatelessWidget 不帶綁定狀態(tài)刨摩,而 StatefulWidget 帶綁定狀態(tài),其依賴的數(shù)據(jù)在 Widget 生命周期中可能會頻繁地發(fā)生變化世吨,由 State創(chuàng)建視圖澡刹,數(shù)據(jù)驅(qū)動視圖更新。

單線程模型

 // 聲明了一個延遲 3 秒返回的 Hello Flutter   的 Future耘婚,
    Future<String> fetchContent() async {
      await Future.delayed(new Duration(seconds: 3));
      return 'Hello Flutter';
    }

    /**在Dart中罢浇,有await標(biāo)記的運算,其結(jié)果值都是一個Future對象沐祷,
     * 對于異步函數(shù)返回的 Future 對象嚷闭,如果調(diào)用者決定同步等待, 則需要在調(diào)用處使用 await 關(guān)鍵字赖临,
     * 并且在調(diào)用處的函數(shù)體使用 async 關(guān)鍵字胞锰。
     * Dart 中的 await 并不是阻塞等待,而是異步等待兢榨,Dart 會將調(diào)用體的函數(shù)也視作異步函數(shù)嗅榕,
     * 將等待語句的上下文放入 Event Queue 中,一旦有了結(jié)果吵聪,Event Loop 就會把它從 Event Queue 中取出凌那,等待代碼繼續(xù)執(zhí)行。
     */
    //await 與 async 有效區(qū)間只對調(diào)用上下文的函數(shù)有效吟逝,并不向上傳遞


    testAwaitAndAsync() async {
      String data = await fetchContent();
      print('-----${data}-----');  //等待3秒后打印Hello Flutter   然后打印123
      print('----123------');
    }

Event Loop 完整版的流程圖
在 Dart 中帽蝶,實際上有兩個隊列,一個事件隊列(Event Queue)块攒,另一個則是微任務(wù)隊列(Microtask Queue)励稳。在每一次事件循環(huán)中,Dart 總是先去第一個微任務(wù)隊列中查詢是否有可執(zhí)行的任務(wù)囱井,如果沒有麦锯,才會處理后續(xù)的事件隊列的流程。


Isolate

Dart 也提供了多線程機(jī)制琅绅,即 Isolate。在 Isolate 中鹅巍,資源隔離做得非常好千扶,每個 Isolate 都有自己的 Event Loop 與 Queue料祠,Isolate 之間不共享任何資源,只能依靠消息機(jī)制通信澎羞,因此也就沒有資源搶占問題髓绽。

Isolate 通過發(fā)送管道(SendPort)實現(xiàn)消息通信機(jī)制。我們可以在啟動并發(fā) Isolate 時將主 Isolate 的發(fā)送管道作為參數(shù)傳給它妆绞,這樣并發(fā) Isolate 就可以在任務(wù)執(zhí)行完畢后利用這個發(fā)送管道給我們發(fā)消息了顺呕。
,在 Isolate 中括饶,發(fā)送管道是單向的:我們啟動了一個 Isolate 執(zhí)行某項任務(wù)株茶,Isolate 執(zhí)行完畢后,發(fā)送消息告知我們图焰。如果 Isolate 執(zhí)行任務(wù)時启盛,需要依賴主 Isolate 給它發(fā)送參數(shù),執(zhí)行完畢后再發(fā)送執(zhí)行結(jié)果給主 Isolate技羔,這樣雙向通信的場景我們?nèi)绾螌崿F(xiàn)呢僵闯?答案也很簡單,讓并發(fā) Isolate 也回傳一個發(fā)送管道即可藤滥。

跨組件通訊

Flutter 與 Android iOS 原生的通信有以下三種方式

BasicMessageChannel 實現(xiàn) Flutter 與 原生(Android 鳖粟、iOS)雙向通信 ,主要是傳遞字符串json等數(shù)據(jù)和一些半結(jié)構(gòu)體的數(shù)據(jù)拙绊,
MethodChannel 實現(xiàn) Flutter 與 原生原生(Android 向图、iOS)雙向通信, 用于傳遞方法調(diào)用
EventChannel 實現(xiàn) 原生原生(Android 时呀、iOS)向Flutter 發(fā)送消息 张漂,用于數(shù)據(jù)流(event streams)的通信

平臺視圖 Flutter端使用原生視圖

Flutter 提供了一個平臺視圖(Platform View)的概念。它提供了一種方法谨娜,允許開發(fā)者在 Flutter 里面嵌入原生系統(tǒng)(Android 和 iOS)的視圖

  • 首先航攒,由作為客戶端的 Flutter,通過向原生視圖的 Flutter 封裝類(在 iOS 和 Android 平臺分別是 UIKitView 和 AndroidView)傳入視圖標(biāo)識符趴梢,用于發(fā)起原生視圖的創(chuàng)建請求漠畜;
  • 然后,原生代碼側(cè)將對應(yīng)原生視圖的創(chuàng)建交給平臺視圖工廠(PlatformViewFactory)實現(xiàn)坞靶;
  • 最后憔狞,在原生代碼側(cè)將視圖標(biāo)識符與平臺視圖工廠進(jìn)行關(guān)聯(lián)注冊,讓 Flutter 發(fā)起的視圖創(chuàng)建請求可以直接找到對應(yīng)的視圖創(chuàng)建工廠彰阴。

class SampleView extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    //使用Android平臺的AndroidView瘾敢,傳入唯一標(biāo)識符sampleView
    if (defaultTargetPlatform == TargetPlatform.android) {
      return AndroidView(viewType: 'sampleView');
    } else {
      //使用iOS平臺的UIKitView,傳入唯一標(biāo)識符sampleView
      return UiKitView(viewType: 'sampleView');
    }
  }
}

我們分別創(chuàng)建了平臺視圖工廠和原生視圖封裝類,并通過視圖工廠的 create 方法簇抵,將它們關(guān)聯(lián)起來


//視圖工廠類
class SampleViewFactory extends PlatformViewFactory {
    private final BinaryMessenger messenger;
    //初始化方法
    public SampleViewFactory(BinaryMessenger msger) {
        super(StandardMessageCodec.INSTANCE);
        messenger = msger;
    }
    //創(chuàng)建原生視圖封裝類庆杜,完成關(guān)聯(lián)
    @Override
    public PlatformView create(Context context, int id, Object obj) {
        return new SimpleViewControl(context, id, messenger);
    }
}
//原生視圖封裝類
class SimpleViewControl implements PlatformView {
    private final View view;//緩存原生視圖
    //初始化方法,提前創(chuàng)建好視圖
    public SimpleViewControl(Context context, int id, BinaryMessenger messenger) {
        view = new View(context);
        view.setBackgroundColor(Color.rgb(255, 0, 0));
    }
    
    //返回原生視圖
    @Override
    public View getView() {
        return view;
    }
    //原生視圖銷毀回調(diào)
    @Override
    public void dispose() {
    }
}


protected void onCreate(Bundle savedInstanceState) {
  ...
  Registrar registrar =    registrarFor("samples.chenhang/native_views");//生成注冊類
  SampleViewFactory playerViewFactory = new SampleViewFactory(registrar.messenger());//生成視圖工廠

registrar.platformViewRegistry().registerViewFactory("sampleView", playerViewFactory);//注冊視圖工廠
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末碟摆,一起剝皮案震驚了整個濱河市晃财,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌典蜕,老刑警劉巖断盛,帶你破解...
    沈念sama閱讀 216,591評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異愉舔,居然都是意外死亡钢猛,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,448評論 3 392
  • 文/潘曉璐 我一進(jìn)店門屑宠,熙熙樓的掌柜王于貴愁眉苦臉地迎上來厢洞,“玉大人,你說我怎么就攤上這事典奉√煞” “怎么了?”我有些...
    開封第一講書人閱讀 162,823評論 0 353
  • 文/不壞的土叔 我叫張陵卫玖,是天一觀的道長公你。 經(jīng)常有香客問我,道長假瞬,這世上最難降的妖魔是什么陕靠? 我笑而不...
    開封第一講書人閱讀 58,204評論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮脱茉,結(jié)果婚禮上剪芥,老公的妹妹穿的比我還像新娘。我一直安慰自己琴许,他們只是感情好税肪,可當(dāng)我...
    茶點故事閱讀 67,228評論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著榜田,像睡著了一般益兄。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上箭券,一...
    開封第一講書人閱讀 51,190評論 1 299
  • 那天净捅,我揣著相機(jī)與錄音,去河邊找鬼辩块。 笑死蛔六,一個胖子當(dāng)著我的面吹牛荆永,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播国章,決...
    沈念sama閱讀 40,078評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼屁魏,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了捉腥?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,923評論 0 274
  • 序言:老撾萬榮一對情侶失蹤你画,失蹤者是張志新(化名)和其女友劉穎抵碟,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體坏匪,經(jīng)...
    沈念sama閱讀 45,334評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡拟逮,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,550評論 2 333
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了适滓。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片敦迄。...
    茶點故事閱讀 39,727評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖凭迹,靈堂內(nèi)的尸體忽然破棺而出罚屋,到底是詐尸還是另有隱情,我是刑警寧澤嗅绸,帶...
    沈念sama閱讀 35,428評論 5 343
  • 正文 年R本政府宣布脾猛,位于F島的核電站,受9級特大地震影響鱼鸠,放射性物質(zhì)發(fā)生泄漏猛拴。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,022評論 3 326
  • 文/蒙蒙 一蚀狰、第九天 我趴在偏房一處隱蔽的房頂上張望愉昆。 院中可真熱鬧,春花似錦麻蹋、人聲如沸跛溉。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,672評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽倒谷。三九已至,卻和暖如春糙箍,著一層夾襖步出監(jiān)牢的瞬間渤愁,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,826評論 1 269
  • 我被黑心中介騙來泰國打工深夯, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留抖格,地道東北人诺苹。 一個月前我還...
    沈念sama閱讀 47,734評論 2 368
  • 正文 我出身青樓,卻偏偏與公主長得像雹拄,于是被迫代替她去往敵國和親收奔。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,619評論 2 354

推薦閱讀更多精彩內(nèi)容