你好,F(xiàn)lutter

什么是Flutter

2018年2月27日,在2018世界移動(dòng)大會(huì)上,Google發(fā)布了Flutter的第一個(gè)Beta版本。Flutter是Google用以幫助開(kāi)發(fā)者在Ios和Android兩個(gè)平臺(tái)開(kāi)發(fā)高質(zhì)量原生應(yīng)用的全新移動(dòng)UI框架,點(diǎn)擊查看Flutter介紹視頻

其實(shí)我第一次聽(tīng)說(shuō)Flutter是在收到谷歌開(kāi)發(fā)者公眾號(hào)的推送里,當(dāng)時(shí)讀完了那篇文章覺(jué)得Flutter的優(yōu)點(diǎn)確實(shí)比較突出:

  1. 熱重載(Hot Reload),作為一個(gè)菜鳥(niǎo)安卓開(kāi)發(fā)者,能熱重載真的太舒服了,利用Android Studio直接一個(gè)ctrl+s就可以保存并重載,模擬器立馬就可以看見(jiàn)效果,就這一點(diǎn)比原生安卓制作簡(jiǎn)直不知道高到哪里去了。
  2. 一切皆為Widget的理念,對(duì)于Flutter來(lái)說(shuō),手機(jī)應(yīng)用里的所有東西都是Widget,通過(guò)可組合的空間集合、豐富的動(dòng)畫(huà)庫(kù)以及分層課擴(kuò)展的架構(gòu)實(shí)現(xiàn)了富有感染力的靈活界面設(shè)計(jì)。
  3. 借助可移植的GPU加速的渲染引擎以及高性能本地代碼運(yùn)行時(shí)以達(dá)到跨平臺(tái)設(shè)備的高質(zhì)量用戶(hù)體驗(yàn)。 這段介紹是直接抄下來(lái)的,雖然我并不知道什么叫可移植的GPU加速的渲染引擎,但是最終結(jié)果就是利用Flutter構(gòu)建的應(yīng)用在運(yùn)行效率上會(huì)和原生應(yīng)用差不多。
    酷安上有一個(gè)Flutter的演示Demo,Flutter Gallery
    如果經(jīng)常逛酷安的一定會(huì)發(fā)現(xiàn)這個(gè)畫(huà)廊的演示Demo的圖標(biāo)和另一個(gè)演示Demo的圖標(biāo)是一樣的,Google Fuchsia OS Preview,這個(gè)應(yīng)用的是傳聞的Google正在研發(fā)的新一代操作系統(tǒng),所以個(gè)人認(rèn)為,F(xiàn)lutter的存在可能不僅僅是實(shí)現(xiàn)在安卓和IOS上的運(yùn)行,更是為了日后豐富Fuchsia這個(gè)新系統(tǒng)的軟件生態(tài)而存在的。

Flutter的核心內(nèi)容

接下來(lái)我想寫(xiě)一下我自己通過(guò)這兩天的接觸對(duì)于Flutter的核心內(nèi)容也就是上面好處的第二點(diǎn)的理解。

一切都是控件(Widget)

在Flutter中,每個(gè)應(yīng)用程序都是Widget,這點(diǎn)和其他的應(yīng)用框架不一樣,F(xiàn)lutter的對(duì)象模型是統(tǒng)一的,也就是控件。
一個(gè)控件可以定義:

  • 結(jié)構(gòu)元素(比如按鈕或者菜單)
  • 風(fēng)格元素(比如字體或者顏色方案)
  • 布局
  • 一些業(yè)務(wù)邏輯
  • 等等。。。。
    控件是基于構(gòu)圖形成層次結(jié)構(gòu),每個(gè)控件嵌套在其中,并從其父代繼承屬性,沒(méi)有單獨(dú)的“應(yīng)用程序”對(duì)象,只有根控件。

您可以通過(guò)告知框架用另一個(gè)控件替換層次結(jié)構(gòu)中的控件來(lái)響應(yīng)事件,比如用戶(hù)交互,然后框架會(huì)對(duì)比新的控件和舊的控件,并有效的更新用戶(hù)界面,即更新有變化的控件。

也就是說(shuō),在Flutter中,一個(gè)應(yīng)用就是有許許多多的Widget組合而成的。

構(gòu)建第一個(gè)Flutter實(shí)例

先來(lái)介紹一下Flutter里面的基本空間:

  • Text:文本控件,在應(yīng)用中創(chuàng)建各種樣式的文本。
  • Row,Column:Flex控件,可以創(chuàng)建水平(Row)或垂直(Column)方向的布局,是基于Web的flexbox的布局模式設(shè)計(jì)的。
  • Stack:非線(xiàn)性布局(水平或垂直),控件可以堆疊在其他控件上,可以使用Positioned控件控制Stack相對(duì)頂部、右部、底部和左部的位置,是基于Web的absolute定位的布局模式。
  • Container:創(chuàng)建矩形的可視元素,可以用BoxDecoration來(lái)設(shè)計(jì)樣式,比如背景、邊框和陰影,Container也有邊距、填充和大小限制,另外,還可以在三維空間利用矩陣進(jìn)行變換。

結(jié)合實(shí)例分析:

import 'package:flutter/material.dart';

class MyAppBar extends StatelessWidget {
  MyAppBar({this.title});

  final Widget title;

  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return new Container(
      height: 56.0,
      padding: const EdgeInsets.symmetric(horizontal: 8.0),
      decoration: new BoxDecoration(color: Colors.blue[500]),
      //new Row意味著該子布局為水平布局
      child: new Row(
        children: <Widget>[
          //布局依次為圖標(biāo)按鈕,剩余容器和圖標(biāo)按鈕,如果把第二個(gè)IconButton移動(dòng)到Expanded前則內(nèi)容會(huì)發(fā)生改變
          new IconButton(
              icon: new Icon(Icons.menu),
              tooltip: '導(dǎo)航菜單',
              onPressed: null
          ),
          //Expanded的作用可以使用剩余的所有空間。
          new Expanded(
              child: title
          ),
          new IconButton(
              icon: new Icon(Icons.search),
              tooltip: '搜索',
              onPressed: null
          )
        ],
      ),
    );
  }
}

class MyScaffold extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return new Material(
      child: new Column(
        children: <Widget>[
          new MyAppBar(
            title: new Text(
              '示例標(biāo)題',
              style: Theme
                  .of(context)
                  .primaryTextTheme
                  .title,
            ),
          ),
          new Expanded(
            child: new Center(
              child: new Text('你好世界!'),
            ),
          )
        ],
      ),
    );
  }
}

void main() {
  runApp(new MaterialApp(
    title: '我的應(yīng)用',
    home: new MyScaffold(),
  ));
}

其實(shí)說(shuō)真的我第一眼看到這段代碼的時(shí)候,第一想法就是,為什么會(huì)有這么多括號(hào)?但是這不是重點(diǎn),有點(diǎn)編程經(jīng)驗(yàn)的都知道要先從main函數(shù)看起,這里的main函數(shù)里面套了一個(gè)runApp函數(shù),

runApp函數(shù)接受指定的控件(Widget),并使其作為控件樹(shù)(widget tree)的根控件。

runApp里面new了一個(gè)MaterialApp對(duì)象,然后這個(gè)對(duì)象有兩個(gè)參數(shù),第一個(gè)是titile,指明了這個(gè)控件的標(biāo)題是啥,第二個(gè)參數(shù)是home,指明了這個(gè)控件的主體是啥。
再深入的看就會(huì)發(fā)現(xiàn),home的值是一個(gè)new出來(lái)的MyScaffold對(duì)象,這時(shí)我們就可以去查看MyScaffold這個(gè)類(lèi)的聲明代碼。

MyScaffold控件為子控件設(shè)置垂直布局,在垂直頂部放置一個(gè)MyAppBar的實(shí)例(這個(gè)控件也是自己創(chuàng)建的),將MyAppBar的Text控件作為標(biāo)題使用,將控件作為參數(shù)傳遞給其他控件非常方便實(shí)用的,你可以創(chuàng)建通用的控件,以各種方式重復(fù)的使用。最后,MyScaffold使用Expanded,用一個(gè)中心文本來(lái)填充剩余的空間。

MyAppBar控件創(chuàng)建了一個(gè)Container(容器),高度為56設(shè)備無(wú)關(guān)像素(device-independent pixels),內(nèi)部左右填充8像素(pixels)。在容器內(nèi)部,MyAppBar為子控件設(shè)置Row(水平)布局,中間的title控件被設(shè)置成Expanded,Expanded的作用是展開(kāi)Row、Column和Flex的子控件,意味它可以使用剩余的所有空間。

其實(shí)上述的分析過(guò)程就是一個(gè)對(duì)控件數(shù)的一個(gè)遍歷,從根控件到里面的子控件,F(xiàn)lutter的設(shè)計(jì)理念就是一切皆為控件,組件套組建。雖然上述代碼不是java,c等主流代碼,但是理解起來(lái)卻并不是非常難懂,上手難度確實(shí)不大,值得體驗(yàn)。

最后,推薦一些鏈接:
Flutter官網(wǎng)
Flutter教程
Flutter中文開(kāi)發(fā)者論壇

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

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