iT邦幫忙

2021 iThome 鐵人賽

DAY 13
0

彈性佈局

介紹完線性排列的佈局方式,今天我們談談另外的配置方式的佈局組件。

挑戰目標

學習 widget

  • Flex
    • Expanded
    • Spacer
  • Stack
    • Positioned
  • Align

Flex

Flex 是可以主軸為排列方向的組件,Row 和 Column 也只是繼承 Flex 而來的,因此它們三個之間的參數設定其實大同小異,Flex 可以設定 direction 屬性為 Axis.vertical 或是 Axis.horizontal,確認主軸方向的話,可以直接使用 Row 和 Column 從字面上會比較直覺。

不過既然名稱命名為 Flex (彈性) 就代表這個組件比起其他佈局組件應該會具備一些不一樣的特色功能,這個就需要搭配ExpandedSpacer這兩個組件的設定。

注意:這兩個參數的使用只能夠應用在 Flex、Column、Row的children,若搭配其他佈局組件會發生錯誤。

  • Expanded

Flex組件類別下的子元素設定,可以透過flex設定占用的主軸的空間比例大小,這個強制將 child 擴展成對應的比例大小。

我們從下方的範例來看,在一個容器高度為100的空間中使用 Flex 組件設定主軸方向為 vertical。上面配置文字區塊顯示"德國",下面在使用 Expanded 配合 flex 屬性為 1 完成了國旗的呈現。這邊的子元素扣除文字所需的高度後,將主軸上剩下的空間平均配置給了德國國旗的三個顏色方塊。

    var theFlex = Container(
      width: 150,
      height: 145,
      decoration: BoxDecoration(
        border: Border.all(color: Colors.blueAccent),
      ),
      child: Flex(
        direction: Axis.vertical,
        children: [
          Container(
            child: Text("德國"),
          ),
          Expanded(
            flex: 1,
            child: Container(
              color: Color(0xFF000000),
            ),
          ),
          Expanded(
            flex: 1,
            child: Container(
              color: Color(0xFFFF0000),
            ),
          ),
          Expanded(
            flex: 1,
            child: Container(
              color: Color(0xFFFFCC00),
            ),
          ),
        ],
      ),
    );

widget_expanded

  • Spacer

Spacer 只有具有 flex 單一屬性,不過沒有 child,主要用來填補組件中間的空白位置。

Stack

Stack 的佈局方式與css中的絕對定位很類似,可以透過四個邊(top、left、right、bottom)的距離設定對應的位置,這個組件可將子元素一個一個堆疊到一個空間上,其子元素需要使用Positioned設定位置參數。

var theStack = Container(
      width: 300,
      height: 150,
      color: Colors.blue[300],
      child: Stack(
        children: [
          square,
          Positioned(
            top: 50.0,
            left: 50.0,
            child: square,
          ),
          Positioned(
            bottom: 50.0,
            right: 0.0,
            child: square,
          ),
        ],
      ),
    );

第一個綠色方塊,我沒有使用Positioned指定,因此會出現在預設的"原點"上。第二個元素。

第二個綠色方塊,給定top 50.0 left 50.0,定位在離左邊和上面各50的距離。

第三個綠色方塊,給定right 0.0 bottom 50.0,定位在離右邊的邊上以及離底部50的距離。

widget_stack

Align

比起 Stack 搭配 Positioned,若只有一個子元素需要座標的定位時,Align可以提供簡單的佈局配置,範例如下。

屬性alignment是從抽象類別AlignmentGeometry來的,這個抽象類別的定位方式可以簡單的使用AlignmentDirectional設定,也可以用根據原點Alignment照比例的方式做配置。

    var theAlignWithAlignment = Container(
      width: 200,
      height: 100,
      margin: const EdgeInsets.all(5.0),
      color: Colors.blue[300],
      child: Align(
        // 同等於 Alignment(0.0, -1.0)
        alignment: AlignmentDirectional.topCenter,
        child: square,
      ),
    );

widget_align

Alignment(0.0, 0.0) 預設是以容器的中心點為原點,若想要改變成較習慣的左上角為原點,可以改用
FractionalOffset 進行設定。

    var theAlignWithFractionalOffset = Container(
      width: 200,
      height: 100,
      margin: const EdgeInsets.all(5.0),
      color: Colors.blue[300],
      child: Align(
        alignment: FractionalOffset(0.0, 0.0),
        child: square,
      ),
    );

widget_align_2

小結

練習成果

今日學習了在 Expanded、Spacer 可以在有主軸設定的組件上調整組件的位置,在線性排列上多了更多的彈性;另外也介紹了 Stack 與 Align 可以在一個容器的區塊,透過絕對路徑的設定讓組件呈現在想要的座標位置上。


上一篇
Flutter體驗 Day 12-線性佈局
下一篇
Flutter體驗 Day 14-容器組件
系列文
Flutter / Dart 跨平台App開發體驗30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言