第四章: 布局類組件 4.3 線性布局(Row和Column)

跟隨《Flutter實(shí)戰(zhàn)·第二版》學(xué)習(xí),建議直接看原書

所謂線性布局,即指沿水平或垂直方向排列子組件。Flutter 中通過Row和Column來實(shí)現(xiàn)線性布局,類似于Android 中的LinearLayout控件。Row和Column都繼承自Flex咆霜,我們將在彈性布局一節(jié)中詳細(xì)介紹Flex

主軸和縱軸

對于線性布局,有主軸和縱軸之分嘶朱,如果布局是沿水平方向蛾坯,那么主軸就是指水平方向,而縱軸即垂直方向疏遏;如果布局沿垂直方向偿衰,那么主軸就是指垂直方向挂疆,而縱軸就是水平方向。在線性布局中下翎,有兩個(gè)定義對齊方式的枚舉類MainAxisAlignment和CrossAxisAlignment缤言,分別代表主軸對齊和縱軸對齊。

Row

Row可以沿水平方向排列其子widget视事。定義如下:

Row({
  ...  
  TextDirection textDirection,    
  MainAxisSize mainAxisSize = MainAxisSize.max,    
  MainAxisAlignment mainAxisAlignment = MainAxisAlignment.start,
  VerticalDirection verticalDirection = VerticalDirection.down,  
  CrossAxisAlignment crossAxisAlignment = CrossAxisAlignment.center,
  List<Widget> children = const <Widget>[],
})
  • textDirection:表示水平方向子組件的布局順序(是從左往右還是從右往左)胆萧,默認(rèn)為系統(tǒng)當(dāng)前Locale環(huán)境的文本方向(如中文、英語都是從左往右俐东,而阿拉伯語是從右往左)跌穗。
  • mainAxisSize:表示Row在主軸(水平)方向占用的空間,默認(rèn)是MainAxisSize.max虏辫,表示盡可能多的占用水平方向的空間蚌吸,此時(shí)無論子 widgets 實(shí)際占用多少水平空間,Row的寬度始終等于水平方向的最大寬度砌庄;而MainAxisSize.min表示盡可能少的占用水平空間羹唠,當(dāng)子組件沒有占滿水平剩余空間,則Row的實(shí)際寬度等于所有子組件占用的的水平空間娄昆;
  • mainAxisAlignment:表示子組件在Row所占用的水平空間內(nèi)對齊方式佩微,如果mainAxisSize值為MainAxisSize.min,則此屬性無意義萌焰,因?yàn)樽咏M件的寬度等于Row的寬度哺眯。只有當(dāng)mainAxisSize的值為MainAxisSize.max時(shí),此屬性才有意義扒俯,MainAxisAlignment.start表示沿textDirection的初始方向?qū)R奶卓,如textDirection取值為TextDirection.ltr時(shí),則MainAxisAlignment.start表示左對齊撼玄,textDirection取值為TextDirection.rtl時(shí)表示從右對齊夺姑。而MainAxisAlignment.end和MainAxisAlignment.start正好相反;MainAxisAlignment.center表示居中對齊互纯。讀者可以這么理解:textDirection是mainAxisAlignment的參考系瑟幕。
  • verticalDirection:表示Row縱軸(垂直)的對齊方向磕蒲,默認(rèn)是VerticalDirection.down留潦,表示從上到下。
  • crossAxisAlignment:表示子組件在縱軸方向的對齊方式辣往,Row的高度等于子組件中最高的子元素高度兔院,它的取值和MainAxisAlignment一樣(包含start、end站削、 center三個(gè)值)坊萝,不同的是crossAxisAlignment的參考系是verticalDirection,即verticalDirection值為VerticalDirection.down時(shí)crossAxisAlignment.start指頂部對齊,verticalDirection值為VerticalDirection.up時(shí)十偶,crossAxisAlignment.start指底部對齊菩鲜;而crossAxisAlignment.end和crossAxisAlignment.start正好相反;
  • children :子組件數(shù)組惦积。
示例
Column(
              // 測試Row對齊方式 排除Column默認(rèn)居中對齊的干擾
              crossAxisAlignment: CrossAxisAlignment.start,
              children: <Widget>[
                Row(
                  mainAxisAlignment: MainAxisAlignment.center,
                  children: <Widget>[
                    Text(" Hello World "),
                    Text(" I'm Jack "),
                  ],
                ),
                Row(
                  mainAxisSize: MainAxisSize.min,
                  mainAxisAlignment: MainAxisAlignment.center,
                  children: <Widget>[
                    Text(" Hello World "),
                    Text(" I'm Jack "),
                  ],
                ),
                Row(
                  mainAxisAlignment: MainAxisAlignment.end,
                  textDirection: TextDirection.rtl,
                  children: <Widget>[
                    Text(" Hello World "),
                    Text(" I'm Jack "),
                  ],
                ),
                Row(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  verticalDirection: VerticalDirection.up,
                  children: <Widget>[
                    Text(" Hello World ", style: TextStyle(fontSize: 30)),
                    Text(" I'm Jack "),
                  ],
                ),
              ],
            )
Simulator Screen Shot - iPhone 13.png

解釋:第一個(gè)Row很簡單接校,默認(rèn)為居中對齊;第二個(gè)Row狮崩,由于mainAxisSize值為MainAxisSize.min蛛勉,Row的寬度等于兩個(gè)Text的寬度和,所以對齊是無意義的睦柴,所以會從左往右顯示诽凌;第三個(gè)Row設(shè)置textDirection值為TextDirection.rtl,所以子組件會從右向左的順序排列坦敌,而此時(shí)MainAxisAlignment.end表示左對齊侣诵,所以最終顯示結(jié)果就是圖中第三行的樣子;第四個(gè) Row 測試的是縱軸的對齊方式恬试,由于兩個(gè)子 Text 字體不一樣窝趣,所以其高度也不同,我們指定了verticalDirection值為VerticalDirection.up训柴,即從低向頂排列哑舒,而此時(shí)crossAxisAlignment值為CrossAxisAlignment.start表示底對齊

Column

Column可以在垂直方向排列其子組件。參數(shù)和Row一樣幻馁,不同的是布局方向?yàn)榇怪毕赐遥鬏S縱軸正好相反,讀者可類比Row來理解仗嗦,下面看一個(gè)例子:

Column(
      crossAxisAlignment: CrossAxisAlignment.center,
      children: <Widget>[
        Text("hi"),
        Text("world"),
      ],
    );
image.png

解釋:

  • 由于我們沒有指定Column的mainAxisSize膘滨,所以使用默認(rèn)值MainAxisSize.max,則Column會在垂直方向占用盡可能多的空間稀拐,此例中會占滿整個(gè)屏幕高度
  • 由于我們指定了 crossAxisAlignment 屬性為CrossAxisAlignment.center火邓,那么子項(xiàng)在Column縱軸方向(此時(shí)為水平方向)會居中對齊。注意德撬,在水平方向?qū)R是有邊界的铲咨,總寬度為Column占用空間的實(shí)際寬度,而實(shí)際的寬度取決于子項(xiàng)中寬度最大的Widget蜓洪。在本例中纤勒,Column有兩個(gè)子Widget,而顯示“world”的Text寬度最大隆檀,所以Column的實(shí)際寬度則為Text("world") 的寬度摇天,所以居中對齊后Text("hi")會顯示在Text("world")的中間部分

實(shí)際上粹湃,Row和Column都只會在主軸方向占用盡可能大的空間,而縱軸的長度則取決于他們最大子元素的長度泉坐。如果我們想讓本例中的兩個(gè)文本控件在整個(gè)手機(jī)屏幕中間對齊为鳄,我們有兩種方法:

  • 將Column的寬度指定為屏幕寬度;這很簡單腕让,我們可以通過ConstrainedBox或SizedBox(我們將在后面章節(jié)中專門介紹這兩個(gè)Widget)來強(qiáng)制更改寬度限制济赎,例如:
ConstrainedBox(
          constraints: BoxConstraints(minWidth: double.infinity),
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.center,
            children: <Widget>[
              Text("hi"),
              Text("world"),
            ],
          ),
        ),
image.png
特殊情況

如果Row里面嵌套Row,或者Column里面再嵌套Column记某,那么只有最外面的Row或Column會占用盡可能大的空間司训,里面Row或Column所占用的空間為實(shí)際大小,下面以Column為例說明:

Container(
          color: Colors.green,
          child: Padding(
            padding: EdgeInsets.all(16.0),
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              mainAxisSize: MainAxisSize.max, //有效 外層Column高度為整個(gè)屏幕
              children: <Widget>[
                Container(
                  color: Colors.red,
                  child: Column(
                    mainAxisSize: MainAxisSize.max, // 無效 內(nèi)層Column高度為實(shí)際高度
                    children: <Widget>[
                      Text(" hello world "),
                      Text("I am Jack"),
                    ],
                  ),
                ),
              ],
            ),
          ),
        ),
Simulator Screen Shot - iPhone 13.png

如果要讓里面的Column占滿外部Column液南,可以使用Expanded 組件:

Container(
          color: Colors.green,
          child: Padding(
            padding: EdgeInsets.all(16.0),
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              mainAxisSize: MainAxisSize.max, //有效 外層Column高度為整個(gè)屏幕
              children: <Widget>[

                Expanded(
                  child: Container(
                    color: Colors.red,
                    child: Column(
                      mainAxisAlignment: MainAxisAlignment.center,
                      children: <Widget>[
                        Text(" hello world "),
                        Text("I am Jack"),
                      ],
                    ),
                  ),
                ),

              ],
            ),
          ),
        ),
Simulator Screen Shot - iPhone 13.png
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末壳猜,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子滑凉,更是在濱河造成了極大的恐慌统扳,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,723評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件畅姊,死亡現(xiàn)場離奇詭異咒钟,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)若未,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,485評論 2 382
  • 文/潘曉璐 我一進(jìn)店門朱嘴,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人粗合,你說我怎么就攤上這事萍嬉。” “怎么了隙疚?”我有些...
    開封第一講書人閱讀 152,998評論 0 344
  • 文/不壞的土叔 我叫張陵壤追,是天一觀的道長。 經(jīng)常有香客問我供屉,道長行冰,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,323評論 1 279
  • 正文 為了忘掉前任伶丐,我火速辦了婚禮悼做,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘撵割。我一直安慰自己贿堰,他們只是感情好辙芍,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,355評論 5 374
  • 文/花漫 我一把揭開白布啡彬。 她就那樣靜靜地躺著羹与,像睡著了一般。 火紅的嫁衣襯著肌膚如雪庶灿。 梳的紋絲不亂的頭發(fā)上纵搁,一...
    開封第一講書人閱讀 49,079評論 1 285
  • 那天,我揣著相機(jī)與錄音往踢,去河邊找鬼腾誉。 笑死,一個(gè)胖子當(dāng)著我的面吹牛峻呕,可吹牛的內(nèi)容都是我干的利职。 我是一名探鬼主播,決...
    沈念sama閱讀 38,389評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼瘦癌,長吁一口氣:“原來是場噩夢啊……” “哼猪贪!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起讯私,我...
    開封第一講書人閱讀 37,019評論 0 259
  • 序言:老撾萬榮一對情侶失蹤热押,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后斤寇,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體桶癣,經(jīng)...
    沈念sama閱讀 43,519評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,971評論 2 325
  • 正文 我和宋清朗相戀三年娘锁,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了牙寞。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,100評論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡莫秆,死狀恐怖碎税,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情馏锡,我是刑警寧澤雷蹂,帶...
    沈念sama閱讀 33,738評論 4 324
  • 正文 年R本政府宣布,位于F島的核電站杯道,受9級特大地震影響匪煌,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜党巾,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,293評論 3 307
  • 文/蒙蒙 一萎庭、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧齿拂,春花似錦闹获、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,289評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽医男。三九已至,卻和暖如春捻勉,著一層夾襖步出監(jiān)牢的瞬間镀梭,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,517評論 1 262
  • 我被黑心中介騙來泰國打工踱启, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留报账,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,547評論 2 354
  • 正文 我出身青樓埠偿,卻偏偏與公主長得像透罢,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子冠蒋,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,834評論 2 345

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