flutter筆記7:flutter頁(yè)面布局基礎(chǔ),看完這篇就可以用flutter寫(xiě)APP了

不知不覺(jué)已經(jīng)到了第7篇罐栈,然而很多萌新玩家可能還是不知道如何堆砌控件黍衙,像用CSS一樣搭出漂亮的APP界面,我也一樣荠诬,紅紅火火恍恍惚惚琅翻,直到今天含淚讀完Flutter布局基礎(chǔ),仿佛打開(kāi)了一個(gè)全新的世界柑贞。

基本概念

在flutter中方椎,一切皆控件!一切皆控件钧嘶!一切皆控件棠众!牢牢記住這個(gè)概念。Text是控件有决,Image是控件闸拿,Icon是控件,布局腳手架也Scaffold也是控件书幕,甚至整個(gè)APP也是控件胸墙。

用戶自定義控件分為有狀態(tài)控件和無(wú)狀態(tài)控件兩種類型,其特性在前面的筆記4中可以感受感受按咒。

flutter的內(nèi)置控件分為兩種:

  • 可視控件(visible widget)。即我們直接看到的控件但骨,如text励七、Icon、Button奔缠,名稱理解和html標(biāo)簽相同掠抬。
  • 布局控件(layout widget)⌒0ィ可以理解為架子两波,如Row瞳步、Column、Container腰奋。布局控件不會(huì)直接呈現(xiàn)內(nèi)容单起,可看作承載可視控件的容器。所有的布局控件都有承載子控件的屬性:childchildren劣坊。child可承載單個(gè)子控件嘀倒,children可承載多個(gè)子控件。每個(gè)布局控件有默認(rèn)的布局方式局冰,使其子控件按照自己的樣式安放到位子上测蘑。布局控件提供了各種樣式的參數(shù),可實(shí)現(xiàn)子控件的對(duì)齊(align)康二、縮放(size)碳胳、包裝(pack)和嵌套(Nest)。簡(jiǎn)單總結(jié)為:布局控件是為了實(shí)現(xiàn)可視控件的各種視覺(jué)效果而做的包裝沫勿,比如前端的html為了實(shí)現(xiàn)sticky挨约、雙飛翼、圣杯等布局常常內(nèi)容區(qū)外層添加div包裹層藕帜。

布局控件也是可以模擬顯示的烫罩,通常用于調(diào)試布局樣式時(shí)用到的網(wǎng)格線、標(biāo)尺洽故、動(dòng)畫(huà)幀等贝攒。啟用方式:
1.在main.dart中,引入包:

import 'package:flutter/rendering.dart' show debugPaintSizeEnabled;

2.在main函數(shù)中打開(kāi)開(kāi)關(guān):

void main() {
  debugPaintSizeEnabled = true;      //打開(kāi)視覺(jué)調(diào)試開(kāi)關(guān)
  runApp(new MyApp());
}

運(yùn)行代碼后APP效果如下:


視覺(jué)調(diào)試模式下的APP界面

flutter的內(nèi)置控件已經(jīng)定義了很多屬性时甚,玩家可以參考Widgets Catalog了解每種控件的詳細(xì)屬性和用法隘弊。本篇通過(guò)幾個(gè)例子,介紹頁(yè)面上的控件如何堆砌和布局荒适。

別著急梨熙,由于下面的案例中,可能用到圖片刀诬,先交待一下加載圖片的基本配置方法:

  1. 到項(xiàng)目根目錄下創(chuàng)建一個(gè)文件夾咽扇,命名:images,將圖片放置到該文件夾中陕壹。
  2. 打開(kāi)根目錄下的pubspec.yaml文件质欲,在其下添加注釋中的屬性:
flutter:
  uses-material-design: true
  assets:                            //如果沒(méi)有這個(gè)屬性則添加到flutter標(biāo)簽下
    - images/lake.jpg          //聲明圖片的路徑
  1. 到代碼中,以image控件的方式引用圖片:
new Image.asset(
              'images/lake.jpg',        //圖片的路徑
              width: 600.0,              //圖片控件的寬度
              height: 240.0,            //圖片控件的高度
              fit: BoxFit.cover,        //告訴引用圖片的控件糠馆,圖像應(yīng)盡可能小嘶伟,但覆蓋整個(gè)控件。
            ),

案例

控件的排列

行(Row)和列(Column)又碌,是flutter中最常用的兩個(gè)布局控件九昧,他們只能容納當(dāng)前屏幕尺寸大小的內(nèi)容绊袋,如果其內(nèi)部的子控件超出屏幕尺寸,不但不會(huì)自動(dòng)生成滾動(dòng)條铸鹰,還會(huì)報(bào)錯(cuò)癌别。

案例1-行排列

橫向排列

如圖上圖所示,圖中有3個(gè)100px寬的圖片掉奄,通過(guò)水平平均間隔的方式居中橫向排列顯示到一行中规个,代碼示例:

 new Center(                //居中控件
  child: new Row(        //行控件
    mainAxisAlignment: MainAxisAlignment.spaceEvenly,      //對(duì)齊方式:平均間隔
    children: [
      new Image.asset('images/pic1.jpg'),        //引入三張圖片
      new Image.asset('images/pic2.jpg'),
      new Image.asset('images/pic3.jpg'),
    ]
  )
)

可以看到上圖用到了2個(gè)布局控件Center和Row,通過(guò)Center包裹Row姓建,使行控件保持居中诞仓,而ROW控件包裹了3個(gè)圖片控件Image,通過(guò)配置Row的mainAxisAlignment對(duì)齊屬性速兔,使三個(gè)圖片空間通過(guò)平均間隔的方式進(jìn)行橫向排列墅拭。

完整代碼:
Dart code: main.dart
Images: images
Pubspec: pubspec.yaml

案例2-列排列

縱向排列

如上圖所示,還是那3張圖涣狗,通過(guò)縱向平均間隔的方式顯示到一列中谍婉,代碼如下:

new Center(
  child: new Column(
    mainAxisAlignment: MainAxisAlignment.spaceEvenly,        //對(duì)齊方式:平均間隔
    children: [
      new Image.asset('images/pic1.jpg'),
      new Image.asset('images/pic2.jpg'),
      new Image.asset('images/pic3.jpg'),
    ]
  )
)

完整代碼:
Dart code: main.dart
Images: images
Pubspec: pubspec.yaml

對(duì)比案例1和2可以看到,代碼結(jié)構(gòu)相同镀钓,Row和Column中都用到了mainAxisAlignment屬性穗熬,除此以外還有crossAxisAlignment屬性。值得注意的是丁溅,在Row中mainAxisAlignment控制水平方向?qū)R唤蔗,crossAxisAlignment控制垂直方向?qū)R,而在Column中則正好相反窟赏。相關(guān)參數(shù)值請(qǐng)參考MainAxisAlignmentCrossAxisAlignment

布局控件的嵌套

案例3-行列嵌套

行列嵌套

如上圖妓柜,我們將圖中的元素按圖中的框線進(jìn)行分解:

1.最外層的使用Row控件包裹,使其內(nèi)部的兩個(gè)子控件:淺藍(lán)色框的菜品介紹和右邊的菜品大圖橫向排列涯穷,代碼如下:

new Scaffold(                                                                              //腳手架控件
      appBar: new AppBar(                                                            //工具欄控件
        title: new Text(widget.title),
      ),
  body: new Center(
  child: new Container(                                                                 //Container控件用于調(diào)整外邊距
    margin: new EdgeInsets.fromLTRB(0.0, 40.0, 0.0, 30.0),        
    height: 600.0,
    child: new Card(                                                                       //Card控件控制卡片的視覺(jué)效果
      child: new Row(                                                                     //Row控件使其子控件橫向排列
        crossAxisAlignment: CrossAxisAlignment.start,                  //縱向?qū)R方式:起始邊對(duì)齊
        children: [
          new Container(                                                                  //Container控件用于調(diào)整寬度
            width: 440.0,   
            child: leftColumn,                                                            //左邊的菜品介紹控件
          ),
          mainImage,                                                                        //右邊的大圖控件
        ],
      ),
    ),
  ),
)
)

2.把淺藍(lán)色框內(nèi)的信息棍掐,用Column包裹,使其內(nèi)容垂直排列:

new Container(
      padding: new EdgeInsets.fromLTRB(20.0, 30.0, 20.0, 20.0),
      child: new Column(                                                                    //Column控件拷况,使其子控件垂直排列
        children: [
          titleText,        //標(biāo)題行作煌,包含了可視Text控件
          subTitle,        //副標(biāo)題行,包含了可視Text控件
          ratings,         //投票信息行
          iconList,        //小圖標(biāo)行
        ],
      ),
    );

3.由于titleText和subTitle都是簡(jiǎn)單的包裝了Text控件赚瘦,不再貼代碼和注釋最疆,重點(diǎn)講下ratings和iconList:


ratings和iconList控件

ratings和iconList控件是垂直排列的兩行,而各自內(nèi)部有自己的布局信息蚤告,因此將這兩行分別拆解為:

ratings

ratings下包含了兩個(gè)水平排列:Row控件用于顯示星級(jí),Text控件用于顯示用戶瀏覽數(shù)服爷。而評(píng)分星級(jí)控件ROW又分解為5個(gè)水平排列的Icon控件杜恰。

iconList控件結(jié)構(gòu)

iconList橫向排列了3個(gè)縱向顯示的控件获诈,層次一目了然。

對(duì)照代碼結(jié)構(gòu):

//ratings控件
new Container(
      padding: new EdgeInsets.all(20.0),
      child: new Row(
        mainAxisAlignment: MainAxisAlignment.spaceEvenly,
        children: [
          new Row(
            mainAxisSize: MainAxisSize.min,       //mainAxisSize心褐,可壓縮或伸長(zhǎng)行內(nèi)控件的間距
            children: [
              new Icon(Icons.star, color: Colors.black),
              new Icon(Icons.star, color: Colors.black),
              new Icon(Icons.star, color: Colors.black),
              new Icon(Icons.star, color: Colors.black),
              new Icon(Icons.star, color: Colors.black),
            ],
          ),
          new Text(
            '170 Reviews',
            style: new TextStyle(
              color: Colors.black,
              fontWeight: FontWeight.w800,
              fontFamily: 'Roboto',
              letterSpacing: 0.5,
              fontSize: 20.0,
            ),
          ),
        ],
      ),
    )

//iconList控件
new Container(
        padding: new EdgeInsets.all(20.0),
        child: new Row(
          mainAxisAlignment: MainAxisAlignment.spaceEvenly,
          children: [
            new Column(
              children: [
                new Icon(Icons.kitchen, color: Colors.green[500]),
                new Text('PREP:'),
                new Text('25 min'),
              ],
            ),
            new Column(
              children: [
                new Icon(Icons.timer, color: Colors.green[500]),
                new Text('COOK:'),
                new Text('1 hr'),
              ],
            ),
            new Column(
              children: [
                new Icon(Icons.restaurant, color: Colors.green[500]),
                new Text('FEEDS:'),
                new Text('4-6'),
              ],
            ),
          ],
        ),
      )

Row和Column可以相互包裹舔涎,使頁(yè)面能夠?qū)崿F(xiàn)整齊的布局,只因其特性總是橫向或縱向充滿父控件逗爹,比如最外層使用時(shí)亡嫌,會(huì)自動(dòng)充滿全屏幕。但是當(dāng)頁(yè)面內(nèi)容需要超出屏幕尺寸時(shí)掘而,就用ListTileListView代替挟冠。

最終顯示效果

完整代碼(由于手機(jī)屏幕尺寸無(wú)法適應(yīng)此案例,運(yùn)行后長(zhǎng)和寬都會(huì)報(bào)溢出錯(cuò)誤袍睡,大家最好使用平板虛擬機(jī)測(cè)試此案例知染,或者調(diào)整代碼中的字體大小和控件尺寸,以滿足顯示要求):
Dart code: main.dart
Images: images
Pubspec: pubspec.yaml

控件的縮放

案例4-縮放

子控件縮放

上圖中斑胜,三個(gè)橫向排列的圖片控件控淡,中間控件的尺寸比兩邊的大一倍,代碼如下:

new Center(
  child: new Row(
    crossAxisAlignment: CrossAxisAlignment.center,
    children: [
      new Expanded(
        child: new Image.asset('images/pic1.jpg'),
      ),
      new Expanded(              //使用Expanded控件對(duì)Image控件進(jìn)行包裹
        flex: 2,                 //flex值默認(rèn)為1止潘,這里改成2之后掺炭,其子控件2倍放大
        child: new Image.asset('images/pic2.jpg'),
      ),
     new Expanded(
        child: new Image.asset('images/pic3.jpg'),
      ),
))

完整代碼:
Dart code: main.dart
Images: images
Pubspec: pubspec.yaml

由于處理邏輯和布局樣式都一起書(shū)寫(xiě)到代碼中,加上控件的嵌套凭戴,flutter的代碼會(huì)如同html的標(biāo)簽一樣嵌套很多層涧狮,對(duì)前端開(kāi)發(fā)者可能需要時(shí)間適應(yīng),但對(duì)我這種新萌來(lái)說(shuō)降低了從CSS和處理代碼之間來(lái)回對(duì)照的麻煩簇宽,并且flutter的內(nèi)置控件默認(rèn)的樣式已經(jīng)十分整潔勋篓,無(wú)需單獨(dú)再學(xué)習(xí)類似前端CSS處理頁(yè)面布局的語(yǔ)法和結(jié)構(gòu),總體來(lái)說(shuō)降低了不少學(xué)習(xí)成本魏割,上手更快更簡(jiǎn)單譬嚣。能在短時(shí)間內(nèi)掌握生產(chǎn)技能,成就感油然而生钞它,自然有繼續(xù)學(xué)下去的動(dòng)力拜银。

以上便是最基礎(chǔ)的排列布局介紹,相信看到這里的小伙伴已經(jīng)明白怎么寫(xiě)APP了遭垛,今天就到這里~感謝大家支持尼桶!
flutter 中文社區(qū)(官方QQ群:338252156)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市锯仪,隨后出現(xiàn)的幾起案子泵督,更是在濱河造成了極大的恐慌,老刑警劉巖庶喜,帶你破解...
    沈念sama閱讀 206,378評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件小腊,死亡現(xiàn)場(chǎng)離奇詭異救鲤,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)秩冈,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,356評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門(mén)本缠,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人入问,你說(shuō)我怎么就攤上這事丹锹。” “怎么了芬失?”我有些...
    開(kāi)封第一講書(shū)人閱讀 152,702評(píng)論 0 342
  • 文/不壞的土叔 我叫張陵楣黍,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我麸折,道長(zhǎng)鳞仙,這世上最難降的妖魔是什么纱新? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 55,259評(píng)論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上风题,老公的妹妹穿的比我還像新娘集晚。我一直安慰自己晌砾,他們只是感情好攀甚,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,263評(píng)論 5 371
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著馁启,像睡著了一般驾孔。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上惯疙,一...
    開(kāi)封第一講書(shū)人閱讀 49,036評(píng)論 1 285
  • 那天翠勉,我揣著相機(jī)與錄音,去河邊找鬼霉颠。 笑死对碌,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的蒿偎。 我是一名探鬼主播朽们,決...
    沈念sama閱讀 38,349評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼诉位!你這毒婦竟也來(lái)了骑脱?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 36,979評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤苍糠,失蹤者是張志新(化名)和其女友劉穎叁丧,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,469評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡歹袁,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,938評(píng)論 2 323
  • 正文 我和宋清朗相戀三年坷衍,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片条舔。...
    茶點(diǎn)故事閱讀 38,059評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖乏矾,靈堂內(nèi)的尸體忽然破棺而出孟抗,到底是詐尸還是另有隱情,我是刑警寧澤钻心,帶...
    沈念sama閱讀 33,703評(píng)論 4 323
  • 正文 年R本政府宣布凄硼,位于F島的核電站,受9級(jí)特大地震影響捷沸,放射性物質(zhì)發(fā)生泄漏摊沉。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,257評(píng)論 3 307
  • 文/蒙蒙 一痒给、第九天 我趴在偏房一處隱蔽的房頂上張望说墨。 院中可真熱鬧,春花似錦苍柏、人聲如沸尼斧。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,262評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)棺棵。三九已至,卻和暖如春熄捍,著一層夾襖步出監(jiān)牢的瞬間烛恤,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,485評(píng)論 1 262
  • 我被黑心中介騙來(lái)泰國(guó)打工余耽, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留缚柏,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,501評(píng)論 2 354
  • 正文 我出身青樓宾添,卻偏偏與公主長(zhǎng)得像船惨,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子缕陕,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,792評(píng)論 2 345