Flutter和Dart系列七:Column和Row

對於線性的佈局排列,Android中使用的是LinearLayout,至於是橫向還是縱向,則是通過orientation屬性來指定的,orientation=vertical表示縱向線性,orientation=horizontal表示橫向線性。在Flutter中,將這兩種線性佈局分別用Column和Row來表示。

  1. Column:orientation=vertical

    void main(){
        runApp(MaterialApp(
            home: MaterialHome(),
        ));
    }
    
    class MaterialHome extends StatelessWidget{
      @override
      Widget build(BuildContext context) {
        return Scaffold(
            appBar: AppBar(
                title: Text("Row_column"),
            ),
            body: Column(
                children: <Widget>[
                    Image.asset("images/pic1.jpg"),
                    Image.asset("images/pic2.jpg"),
                    Image.asset("images/pic3.jpg")
                ],
            ),
        );
      }
    }

    運行效果如下:

    這段代碼需要注意下,由於我們使用了asset資源,所以我們在lib的平級目錄新建一個images目錄,然後將圖片放置到這個目錄下,如圖所示:

    最後還需要在.yaml文件中進行相關配置:

    現在我想讓圖片居中,該如何實現?這裏就需要用到一個屬性:mainAxisAlignment,它的可選值如下:

    • start
    • center
    • end
    • spaceBetween
    • spaceEvenly
    • spaceAround

    實現居中,自然而然想到要使用center:

    body: Column(
        mainAxisAlignment: MainAxisAlignment.center, 
        children: <Widget>[
            Image.asset("images/pic1.jpg"),
            Image.asset("images/pic2.jpg"),
            Image.asset("images/pic3.jpg")
        ],
    ),

     

    至於end,就更好理解了:

    這三個屬性,可以看做是一類,即子Widget之間沒有空隙,它們作爲一個整體放置到靠上、居中、靠下的不同地方。而space開頭的屬性值可以看做一個類別,子Widget之間有空隙: 

    body: Column(
            mainAxisAlignment: MainAxisAlignment.spaceBetween, 
            children: <Widget>[
                Image.asset("images/pic1.jpg"),
                Image.asset("images/pic2.jpg"),
                Image.asset("images/pic3.jpg")
            ],
        ),

    body: Column(
        mainAxisAlignment: MainAxisAlignment.spaceEvenly, 
        children: <Widget>[
            Image.asset("images/pic1.jpg"),
            Image.asset("images/pic2.jpg"),
            Image.asset("images/pic3.jpg")
        ],
    ),

    body: Column(
            mainAxisAlignment: MainAxisAlignment.spaceAround, 
            children: <Widget>[
                Image.asset("images/pic1.jpg"),
                Image.asset("images/pic2.jpg"),
                Image.asset("images/pic3.jpg")
            ],
        ),

    我們可以藉助於LinearLayout的weight屬性來幫助理解:

    • spaceBetween

      <LinearLayout
         orientation="vertical"
         ...>
      
         <ImageView/>
         <View android:layout_weight="1"/>
         <ImageView/>
         <View android:layout_weight="1"/>
         <ImageView/>
      </LinearLayout>   
    • spaceEvenly

      <LinearLayout
         orientation="vertical"
         ...>
         <View android:layout_weight="1"/>
         <ImageView/>
         <View android:layout_weight="1"/>
         <ImageView/>
         <View android:layout_weight="1"/>
         <ImageView/>
         <View android:layout_weight="1"/>
      </LinearLayout>   
    • spaceAround

      <LinearLayout
         orientation="vertical"
         ...>
         <View android:layout_weight="1"/>
         <ImageView/>
         <View android:layout_weight="2"/>
         <ImageView/>
         <View android:layout_weight="2"/>
         <ImageView/>
         <View android:layout_weight="1"/>
      </LinearLayout>   

    當然,要想mainAxisAlignment有效,則需要將mainAxisSize指定爲MainAxisSize.max(默認值)。對於mainAxisSize屬性,它的可選值爲:

    • MainAxisSize.max, 表示儘可能多的佔據垂直方向的空間
    • MainAxisSize.min,表示儘可能少的佔據垂直方向的空間,這種情況下,Column的高度等於子Widget的高度,那麼mainAxisAlignment屬性指定爲任何值都不起作用

    下面介紹Column的另外兩個屬性: crossAxisAlignment和textDirection

    textDirection的可選值爲:

    • TextDirection.ltr:表示水平方向的排列方式爲從左到右
    • TextDirection.rtl:表示水平方向的排列方式爲從右到左

    crossAxisAlignment,表示子Widget在水平方向上的對齊方式,它的可選值爲:

    • start:ltr時,左對齊;rtl,右對齊
    • end:ltr時,右對齊;rtl,左對齊
    • center:居中
    • stretch:填充
    • baseline: 暫時我也不清楚用法

    看下面的例子:

    body: Column(
            mainAxisAlignment: MainAxisAlignment.center,  
            textDirection: TextDirection.ltr,
            crossAxisAlignment: CrossAxisAlignment.start,
    
            children: <Widget>[
                Container(
                    decoration: BoxDecoration(color: Colors.red),
                    height: 60,
                    width: 60,
                ),
                Container(
                    decoration: BoxDecoration(color: Colors.yellow),
                    height: 60,
                    width: 100,
                ),
                Container(
                    decoration: BoxDecoration(color: Colors.blue),
                    height: 60,
                    width: 60,
                )
            ],
        ),

    效果圖如下:

    改爲CrossAxisAlignment.end:

    改爲CrossAxisAlignment.center:

    改爲CrossAxisAlignment.stretch:

    介紹的最後一個屬性爲verticalDirection,可選值爲: - VerticalDirection.down:表示子Widget從上往下排列,默認值 - VerticalDirection.up:表示子Widget從下往上排列,在上例中紅色框就會在下面,藍色跑到了最上面

  2. Expanded

    對於Android中的LinearLayout,有一個屬性我們不得不提:layout_weight。那麼Flutter中有沒有類似Widget呢?

    body: Column(
       children: <Widget>[
           Container(
              decoration: BoxDecoration(color: Colors.red),
              height: 60,
              width: 60,
           ),
            Expanded(
                flex: 1,
                child: Container(
                    decoration: BoxDecoration(color: Colors.yellow),
                    width: 100,
                )),
           Container(
               decoration: BoxDecoration(color: Colors.blue),
               height: 60,
               width: 60,
           )
    
       ],
    ),

    沒錯,就是這個Expanded,運行效果如下:

    那麼如何指定對應的權重值呢?Expanded中有個屬性叫做flex,默認爲1,通過它就可以指定相應的權重值。

  3. Row  orientation=horizontal

    大部分屬性的使用都和Column類似,只不過方向不同而已。只有一個地方需要注意: 在Column中,crossAxisAlignment的參照物是textDirection,而在Row中 crossAxisAlignment參照物變成了verticalDirection,換句話說就是crossAxisAlignment要和verticalDirection一起使用才能決定子Widget在垂直方向的對齊方式。其他的屬性就不再贅述了,大家可以對照Column進行理解。當然,Expanded同樣可以在Row中使用。

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章