国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

用前端 最舒服的躺姿 "搞定" Flutter (組件篇)

Donne / 786人閱讀

摘要:是谷歌的移動(dòng)框架,可以快速在和上構(gòu)建高質(zhì)量的原生用戶界面。在全世界好了這些,大家早就知道了,來點(diǎn)實(shí)在的話說隔壁師兄,閑魚是最早一批與谷歌展開合作,并在重要的商品詳情頁中使用技術(shù)上線的。一切皆來自的組件皆來自。是狀態(tài)不可變的稱為無狀態(tài)。

前言

要說2018年最火的跨端技術(shù),當(dāng)屬于 Flutter 莫屬,應(yīng)該沒人質(zhì)疑吧。一個(gè)新的技術(shù)的趨勢,最明顯的特征,就是它一定想把“前浪”拍死在沙灘上。這個(gè)前浪,就是"react Native","weex"。目前隨便在搜索引擎上 搜索"Flutter reactNative",就全是這兩個(gè)技術(shù)的對比,評測。

一股股濃濃 : 不服來 “掰” 啊 ?。?!的味道。

是的,錯(cuò)過了react Native, weex 這些 “炸” 翻前端的技術(shù),不能在錯(cuò)過 Flutter 了,這年頭,你不會(huì)一門,跨端技術(shù),怎么好意思說自己是【前端】。

Flutter是谷歌的移動(dòng)UI框架,可以快速在iOS和Android上構(gòu)建高質(zhì)量的原生用戶界面。 Flutter可以與現(xiàn)有的代碼一起工作。在全世界... ...

好了, 這些,大家早就知道了,來點(diǎn)實(shí)在的?。?!

話說隔壁師兄,“閑魚” 是最早一批與谷歌展開合作,并在重要的商品詳情頁中使用flutter技術(shù)上線的BU。一路走來,積累了大量的開發(fā)經(jīng)驗(yàn)?!伴e魚” flutter 相關(guān)文章的都很有深度,足見功力。

深入理解Flutter引擎線程模式

Android Flutter實(shí)踐內(nèi)存初探

深入理解flutter的編譯原理與優(yōu)化

... ...

都是一篇篇的深度好文,讀完收益匪淺,但是對于剛接觸 Flutter 的web前端同學(xué)來說還是

好了,回到標(biāo)題,筆者作為一名傳統(tǒng) web前端,想從前端最熟悉的視角 “躺” 著把 Flutter 了解一遍,不要敬仰,平視它?。。∠葟呐d趣開始。

正文

Flutter 環(huán)境的搭建,其實(shí)有很多資源可以參考。這里就不累述了(知道有很多坑,在后續(xù)文章中,有機(jī)會(huì)把個(gè)人遇到的坑匯總一下 )。

有興趣可以參考 flutter安裝環(huán)境的搭建 , 在這里建議各位,一定要自己親自搭一下環(huán)境,跑一下官方demo, 小馬過河,焉知深淺,自己定的位才是最準(zhǔn)確的。

有了環(huán)境,先配置編輯器。

然后 創(chuàng)建一個(gè)Flutter項(xiàng)目。

項(xiàng)目創(chuàng)建完成,可以先用 flutter run 跑一下。

flutter run 

好了,跑起來了吧,你會(huì)看到一個(gè)計(jì)數(shù)的官方示例,點(diǎn)擊加號圖片可以做加運(yùn)算。

這時(shí)候我們看項(xiàng)目的project 目錄里 有一個(gè)入口文件叫 main.dart。然后打開 main.dart 就像下面這樣:

( 為什么你們看到代碼比我的長,因?yàn)槲艺郫B了!!! ) 這不是重點(diǎn),重點(diǎn)是每個(gè)類繼承的都是一個(gè)尾號為Widget 的字符。

聰明的你一定會(huì)覺得 WidgetFlutter 有著某種神秘的聯(lián)系。

“Binggo!",是的,Flutter 有兩個(gè)重型武器,一個(gè)叫 Dart ,另一個(gè)就是 Widget 了。

Dart 一切皆來自 Object, Flutter 的組件皆來自 Widget。
關(guān)于強(qiáng)大的Dart,今天暫且不表,后面有時(shí)間可以獨(dú)立篇幅來聊聊Dart。

先祭出一張 Flutter 的架構(gòu)老圖。

Flutter 的世界里,包括views,view controllers,layouts等在內(nèi)的概念都建立在Widget之上。

WidgetFlutter 組件的抽象描述。所以掌握Flutter的基礎(chǔ)就是學(xué)會(huì)使用 Widget開始。

在Flutter界面渲染過程分為三個(gè)階段:布局、繪制、合成,布局和繪制在Flutter框架中完成,合成則交由引擎負(fù)責(zé):

Flutter 通過組合、嵌套不同類型的控件,就可以構(gòu)建出任意功能、任意復(fù)雜度的界面。

它包含的最主要的幾個(gè)類有:

class WidgetsFlutterBinding extends BindingBase with GestureBinding, ServicesBinding, SchedulerBinding,PaintingBinding, RendererBinding, WidgetsBinding { ... }

abstract class Widget extends DiagnosticableTree { ... }
abstract class StatelessWidget extends Widget { ... }
abstract class StatefulWidget extends Widget { ... }
abstract class RenderObjectWidget extends Widget { ... }
abstract class Element extends DiagnosticableTree implements BuildContext { ... }
abstract class RenderObjectElement extends Element { ... }

class StatelessElement extends ComponentElement { ... }
class StatefulElement extends ComponentElement { ... }
上面這些類的主要作用如下:

基于Flutter控件系統(tǒng)開發(fā)的程序都需要使用WidgetsFlutterBinding,它是Flutter的控件框架和Flutter引擎的膠水層。

Widget就是所有控件的基類,它本身所有的屬性都是只讀的。

RenderObjectWidget所有的實(shí)現(xiàn)類則負(fù)責(zé)提供配置信息并創(chuàng)建具體的RenderObjectElement。

Element是Flutter用來分離控件樹和真正的渲染對象的中間層,控件用來描述對應(yīng)的element屬性,控件重建后可能會(huì)復(fù)用同一個(gè)element。

RenderObjectElement持有真正負(fù)責(zé)布局、繪制和碰撞測試(hit test)的RenderObject對象。

StatelessWidget和StatefulWidget并不會(huì)直接影響RenderObject創(chuàng)建,只負(fù)責(zé)創(chuàng)建對應(yīng)的RenderObjectWidget

StatelessElement和StatefulElement也是類似的功能。

很復(fù)雜是吧,先不用管,簡單表述Widget是這樣的:
Widget = 樣式(css) + 標(biāo)記語義(標(biāo)簽) + 組件化(官方) + 數(shù)據(jù)綁定(props)

“什么?這不就是 react 嗎?"

對, React 的概念和 FlutterWidget 是有相通性的。

“既然有react的概念,難道還有state,setState嗎?“

又對, Flutter 還真有 類似 state 狀態(tài)機(jī)制的概念,而且也確實(shí)有 setState 的方法。

“dome里有兩個(gè)基類,StatelessWidget 和 StatefulWidget 是做什么用的?”

StatelessWidget 和 StatefulWidget,這里兩個(gè)類特別重要,幾乎所有的組件都是基于他們創(chuàng)建的。

StatelessWidget 是狀態(tài)不可變的widget,稱為 無狀態(tài)widget。初始狀態(tài)設(shè)置以后就不可再變化。如果需要變化需要重新創(chuàng)建。

StatefulWidget 可以保存自己的狀態(tài),稱為 有狀態(tài)widgetFlutter 首先保存了初始化時(shí)創(chuàng)建的State,狀態(tài)是通過改變State,來重新構(gòu)建 Widget 樹來進(jìn)行UI變化。改變狀態(tài)的方法,就是我們用的最多的神器"setState",而單純改變數(shù)據(jù)是不會(huì)引發(fā)UI改變的,這個(gè)概念和我們的 React 一樣一樣的。

如果你是初次接觸 Flutter 可以不用記憶這么多組件基類,只用記住以下式子就可以, 不夸張的說,熟悉這個(gè)式子就可以開發(fā) Flutter 項(xiàng)目了:

拆解 圍繞著widget的構(gòu)成,我們來拆解分析一下,標(biāo)記語義,樣式,組件化。 標(biāo)記語義

為什么不稱為 “模版”,“標(biāo)簽”,“element" ,而叫"標(biāo)記語義",是因?yàn)閒lutter的 widget 結(jié)構(gòu)并不只是 “模版”,“標(biāo)簽”,“element"。widget 描述結(jié)構(gòu)更像是 React 的虛擬dom階段,濃縮了相關(guān)上下文,以對象化的結(jié)構(gòu)展示。

我們先來看看,React 創(chuàng)建出來的虛擬dom結(jié)構(gòu)( 偽代碼 ):

var newTree = el("div", {"id": "container"}, [
    el("h1", {style: "color: red"}, ["simple virtal dom"]),
    el("p", ["Hello, virtual-dom"]),
    el("ul", [el("li"), el("li")])
])

再來看看,flutter 用Dart 創(chuàng)建的 widget 代碼結(jié)構(gòu):

Widget build(BuildContext context) {
    return new Column(
      children: [
        new Container(
          padding: new EdgeInsets.only(top:100.0),
          child: new Text("這是一個(gè)組件")
        ),
        new Container(
          decoration: new BoxDecoration(border: new Border.all(width:1.0,color: Colors.blue)),
          padding: new EdgeInsets.all(20.0),
          child: new Text("來自輸入框:"+active)
        )
      ],
    );
  }

是不是這樣看就熟悉很多了。

注:很多前端er 會(huì)不習(xí)慣這中書寫方式,目前有開發(fā)者在社區(qū)推動(dòng),在編譯前,使用jsx標(biāo)簽,編譯后再解析成標(biāo)記樹,比如這個(gè)DSX設(shè)計(jì)的提案。

雖然jsx->標(biāo)記樹 還只是提案,但其實(shí)可以幫助我們更容易理解,此提案想表達(dá)的樣式像這樣:

class MyScaffold extends StatelessWidget {
  build(context) {
    return 
      
          }
          />
          
            
; } }

上面這段 jsx 要是用 Dart 來寫是什么樣的?如下:

class MyScaffold extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Material(
      child: Column(
        children: [
          MyAppBar(
            title: Text(
              "Example title",
               style: Theme.of(context).primaryTextTheme.title,
            ), // Text
          ), // MyAppBar
          Expanded(
            child: Center(
              child: Text("Hello, world!"),
            ), // Center
          ), // Expanded
        ], // []
      ), // Column
    ); // Material
  }
}

雖然 Flutter 與 react 這么類比多少有些牽強(qiáng),但可以個(gè)人總結(jié)一些方法,方便理解:

開頭大寫的類名 相當(dāng)于 jsx 的標(biāo)簽名

child 相當(dāng)于 jsx 的 子標(biāo)簽+布局

children 相當(dāng)于 jsx 的 群組子標(biāo)簽(和child還是有區(qū)別的)

其他屬性相當(dāng)于 jsx 的 props

大家有沒有注意, 第二段dart 語法結(jié)尾都會(huì)帶上 “ // ” 注釋符號,這個(gè)是編輯器IDE在識別是 Flutter 項(xiàng)目后,自動(dòng)追加上去的,像 jsx 語言的標(biāo)簽封閉,方便發(fā)現(xiàn)標(biāo)注的起始節(jié)點(diǎn)。

樣式

對于 Flutter 樣式的理解,可以查看官方的這篇文檔,也是同樣用類比的方式,很直觀的了解,HTML、css樣式和 flutter 之間的聯(lián)系.
可以參考這里:
https://flutter.io/docs/get-s...
https://flutterchina.club/web...

筆者摘選其中樣例的重點(diǎn)部分,對比展示來說明( 由于篇幅問題, 父子關(guān)系css 結(jié)構(gòu),用tab方式來表示 ):

文本樣式:
.demo1 {
      background-color: #e0e0e0;
      width: 320px;
      height: 240px;
      font: 900 24px Georgia;
      letter-spacing: 4px; 
      text-transform: uppercase; 
    }
var demo1 = new Container( 
  child: new Text(
    "Lorem ipsum".toUpperCase(), // 對應(yīng) 左邊的文本轉(zhuǎn)換大小寫
    style: new TextStyle( // 對應(yīng) 左邊的 font
      fontSize: 24.0
      fontWeight: FontWeight.w900,
      fontFamily: "Georgia",
      letterSpacing: 4.0, 
    ),
  ),
  width: 320.0,  // 對應(yīng) 左邊的 width
  height: 240.0,  // 對應(yīng) 左邊的 height
  color: Colors.grey[300],  // 對應(yīng) 左邊的 background-color
);
樣式居中:
.demo2 {
      display: flex;
      align-items: center;
      justify-content: center; 
    }
var demo2 = new Container(
  child:  new Center( // 對應(yīng)左邊的整個(gè) flex 屬性
    child:  new Text("Lorem ipsum")
   )
  );
);
設(shè)置最大(小)寬度:
   
  .container{
   width:300px
   .demo3 {
      width: 100%;
      max-width: 240px; 
   }
  }
// 對于嵌套容器,如果父級的寬度小于子級寬度,則子級容器將自行調(diào)整大小以匹配父級。
var container = new Container(
   child: new Center(
        child: new Text("Lorem ipsum"),
        decoration: new BoxDecoration( ... ), // constraints屬性,創(chuàng)建一個(gè)新的BoxConstraints來設(shè)置minWidth或maxWidth
        width: 240.0, // 對應(yīng)左邊的 max-width
    ),
   width:300.0
  ),
旋轉(zhuǎn)組件:
   
 .box {
       transform: rotate(15deg); 
 }
var container = new Container( // gray box
    child:  new Transform( // 對應(yīng)左邊的 transform
      child:  new Container(  ... ),
      alignment: Alignment.center, // 對應(yīng)左邊的 transform
      transform: new Matrix4.identity() // 對應(yīng)左邊的 transform
        ..rotateZ(15 * 3.1415927 / 180),
    ), 
  )
);
縮放組件:
.box {
      transform: scale(1.5); 
}
var container = new Container( // gray box
    child:  new Transform( // 對應(yīng)左邊的 transform
      child:  new Container(  ... ),
      alignment: Alignment.center, // 對應(yīng)左邊的 transform的中心
      transform: new Matrix4.identity() // 對應(yīng)左邊的 transform
        ..scale(1.5),
    ), 
  )
);
設(shè)置絕對位置和相對位置:
.greybox {
      position: relative; 
     .redbox {
       position: absolute;
       top: 24px;
       left: 24px; 
     }
}
var container = new Container( // grey box
  child: new Stack( // 相對跟容器位置 relative
    children: [
      new Positioned( // 相對父容器位置 absolute
        child:  new Container( ... ),
        left: 24.0,
        top: 24.0,
      )],
  )
);
顏色漸變:
.redbox {
  background: linear-gradient(180deg, #ef5350, rgba(0, 0, 0, 0) 80%); 
}
var container = new Container( // grey box
  child: new Center(
    child: new Container( // red box
      child: new Text( ... ),
      decoration: new BoxDecoration( 
        gradient: new LinearGradient( // 對應(yīng)左邊的 background: linear-gradient
          begin: const Alignment(0.0, -1.0),
          end: const Alignment(0.0, 0.6),
          colors: [
            const Color(0xffef5350),
            const Color(0x00ef5350)
          ],
        ),
      )
    ),
  )
);
圓角:
.box {
  border-radius: 8px; 
}
var container = new Container( // grey box
  child: new Center(
    child: new Container( // red circle
      child: new Text( ... ),
      decoration: new BoxDecoration(
        borderRadius: new BorderRadius.all(
          const Radius.circular(8.0),
        ), 
      )
    ),
  )
);
陰影:
.box {
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.8),
              0 6px 20px rgba(0, 0, 0, 0.5);
}
var container = new Container( // grey box
  child: new Center(
    child: new Container( // red box
      child: new Text( ... ),
      decoration: new BoxDecoration(
        boxShadow: [ // 對應(yīng)左邊的  box-shadow
          new BoxShadow (
            color: const Color(0xcc000000),
            offset: new Offset(0.0, 2.0),
            blurRadius: 4.0,
          ),
          new BoxShadow (
            color: const Color(0x80000000),
            offset: new Offset(0.0, 6.0),
            blurRadius: 20.0,
          ),
        ], 
      )
    ),
  )
);
畫圓:
.circle {
  text-align: center;
  width: 160px;
  height: 160px;
  border-radius: 50%; 
}
var container = new Container( // grey box
  child: new Center(
    child: new Container( // red circle
      child: new Text( ... ),
      decoration: new BoxDecoration(
        color: Colors.red[400],
        shape: BoxShape.circle, // 畫圓和圓角不太一樣,用的是BoxShape繪制圖像能力
      ),
      width: 160.0,
      height: 160.0, 
    ),
  )
);
內(nèi)聯(lián)樣式:
// css 的內(nèi)聯(lián)結(jié)構(gòu)
.greybox {
    font: 900 24px Roboto; 
   .redbox {
       em {
          font: 300 48px Roboto;
          font-style: italic;
      }
    } 
}
var container = new Container( // grey box
  child: new Center(
    child: new Container( // red box
      child:  new RichText(
        text: new TextSpan(
          style: bold24Roboto,
          children: [
            new TextSpan(text: "Lorem "), // 繼承內(nèi)聯(lián)樣式
            new TextSpan(
              text: "ipsum",
              style: new TextStyle( // 具有自定義樣式的多帶帶樣式
                fontWeight: FontWeight.w300,
                fontStyle: FontStyle.italic,
                fontSize: 48.0,
              ),
            ),
          ],
        ),
      ),
    ),
  )
);
組件化

官方的widgets目錄

點(diǎn)擊每一個(gè)card后,里面還有子card, 以一個(gè)展開的緯度來看,是這樣的:

這真是一個(gè)龐大的組件系統(tǒng),這不是社區(qū)提供的,而是官方的。
flutter 團(tuán)隊(duì)事無巨細(xì)的實(shí)現(xiàn)了目前市面上基本上能見到的組件方式和類型。
個(gè)人認(rèn)為這樣做優(yōu)缺點(diǎn)并存的。
先說缺點(diǎn):

1.學(xué)習(xí)成本增加,曲線也還是比較陡峭的。

2.組件直接的繼承關(guān)系路徑比較零亂,比如
繼承自 Widget 是這些大類道還清晰:
PreferredSizeWidget ProxyWidget RenderObjectWidget StatefulWidget StatelessWidget。
但是,StatelessWidget和StatefulWidget的子類就過于平行化了,名稱上晦澀,沒有抽象架構(gòu)化,分層或者塔型級別。

StatelessWidget:

StatefulWidget

3.對自定義組件定義模糊,有這么龐大的組件庫,到底以后是有個(gè)一個(gè)更系統(tǒng)的第三方組件庫去替換它,還是說 Flutter 官方就不建議使用第三方組件,這個(gè)也未有定論。

再說優(yōu)點(diǎn):

1.可以阻止以后輪子泛濫,在團(tuán)隊(duì)僵持不下使用哪個(gè)輪子庫時(shí),最好的理由就是“官方”二字,因?yàn)槭褂霉俜?,可以弱化和?guī)避一些問題,比如: 版本迭代不同步,性能瓶頸,規(guī)范不統(tǒng)一等問題,也能快速支持官方的輔助工具。

2.正是由于官方的標(biāo)準(zhǔn)劃一,為自動(dòng)化編譯,自動(dòng)化搭建,測試調(diào)優(yōu),可視化帶來便利,甚至為Ai前端模型化業(yè)務(wù)場景,提供支撐,都說前端的組件像搭樂高,Flutter就是顆粒標(biāo)準(zhǔn)統(tǒng)一的樂高。

3.天下之勢,分久必合,合久必分。

前端在經(jīng)歷了 flash 一統(tǒng)pc頁面的富媒體時(shí)代,后被喬布斯和H5瓦解;

之后又有H5 的繁盛和框架、語法、構(gòu)建模式的亂戰(zhàn);

再到有“別再更新,老子學(xué)不動(dòng)"的呼聲下,希望有個(gè)一統(tǒng)江湖的跨平臺系統(tǒng)出現(xiàn);

讓開發(fā)者更專注于,提高業(yè)務(wù)內(nèi)容,創(chuàng)造 “新, 酷,炫” 的展現(xiàn)形勢上下功夫。

也許,真有一個(gè)前端江湖的王者的誕生。

寫在最后

實(shí)際的 Flutter Widget 要復(fù)雜的更多的多,在眼花繚亂的 Widget 組件中,筆者想用自己的一些理解,去粗取精,來逐步理解 Flutter 這個(gè)新家伙 ,文中有理解不到位的地方,歡迎大家指正。
筆者團(tuán)隊(duì)也正在開發(fā)一套《Flutter GO》的APP,幫助大家熟悉復(fù)雜的 Flutter Widget。

原文鏈接

更多學(xué)習(xí) Flutter的小伙伴,歡迎入QQ群 Flutter Go :679476515

《Flutter GO》項(xiàng)目地址 alibaba/flutter-go

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/101193.html

相關(guān)文章

  • 前端 舒服躺姿 "搞定" Flutter組件

    摘要:是谷歌的移動(dòng)框架,可以快速在和上構(gòu)建高質(zhì)量的原生用戶界面。在全世界好了這些,大家早就知道了,來點(diǎn)實(shí)在的話說隔壁師兄,閑魚是最早一批與谷歌展開合作,并在重要的商品詳情頁中使用技術(shù)上線的。一切皆來自的組件皆來自。是狀態(tài)不可變的稱為無狀態(tài)。 前言 要說2018年最火的跨端技術(shù),當(dāng)屬于 Flutter 莫屬,應(yīng)該沒人質(zhì)疑吧。一個(gè)新的技術(shù)的趨勢,最明顯的特征,就是它一定想把前浪拍死在沙灘上。這個(gè)...

    LMou 評論0 收藏0
  • 前端 舒服躺姿 "搞定" Flutter組件

    摘要:是谷歌的移動(dòng)框架,可以快速在和上構(gòu)建高質(zhì)量的原生用戶界面。在全世界好了這些,大家早就知道了,來點(diǎn)實(shí)在的話說隔壁師兄,閑魚是最早一批與谷歌展開合作,并在重要的商品詳情頁中使用技術(shù)上線的。一切皆來自的組件皆來自。是狀態(tài)不可變的稱為無狀態(tài)。 前言 要說2018年最火的跨端技術(shù),當(dāng)屬于 Flutter 莫屬,應(yīng)該沒人質(zhì)疑吧。一個(gè)新的技術(shù)的趨勢,最明顯的特征,就是它一定想把前浪拍死在沙灘上。這個(gè)...

    張遷 評論0 收藏0
  • CSS Module

    摘要:樣式變多后,命名將更加混亂。缺點(diǎn)是不能利用成熟的預(yù)處理器或后處理器,和偽類處理起來復(fù)雜。經(jīng)過這樣混淆處理后,名基本就是唯一的,大大降低了項(xiàng)目中樣式覆蓋的幾率。就只能使用預(yù)處理器自己的語法來做樣式復(fù)用了。一 前言CSS 是前端領(lǐng)域中進(jìn)化最慢的一塊。由于 ES2015/2016 的快速普及和 Babel/Webpack 等工具的迅猛發(fā)展,CSS 被遠(yuǎn)遠(yuǎn)甩在了后面,逐漸成為大型項(xiàng)目工程化的痛點(diǎn)。也...

    mingzhong 評論0 收藏0
  • 前端框架中封裝Vue第三方組件的三個(gè)小技巧

      這篇就是帶大家一起學(xué)習(xí)下在封裝第三方組件中,通過封裝的組件去使用第三方組件的Attributes(屬性)、Events(自定義事件)、Methods(方法)、Slots(插槽)以及優(yōu)化技巧?! ∫弧⑹褂玫谌浇M件的屬性  封裝一個(gè)elementUI的el-input輸入框組件稱為myInput,若要在myInput組件上添加一個(gè)disabled屬性來禁用輸入框,這樣的情況要怎么做?  //my...

    3403771864 評論0 收藏0

發(fā)表評論

0條評論

最新活動(dòng)
閱讀需要支付1元查看
<