Flutter控制元件--Row、Column和Stack

android大哥發表於2019-05-22

flutter控制元件練習demo地址github

一 Row 和 Column

1. 簡介

因為 Row 和 Column 都是繼承於 Flex,所以他們兩個的屬性也都是 Flex 的屬性

  • Row 是 Flutter 中常用的控制元件。一個讓 children 在水平方向依次排列 。如果 Row 空間 不足的話。 自身不帶滾動的。
  • Column 也是 Flutter 中常用的控制元件。 一個 children 在垂直方向依次排列 。如果 Column 空間 不足的話。 自身不帶滾動的。

2. 屬性

2.1 mainAxisAlignment (主軸對準方式)

對於 Row 來說 , 水平是主軸。垂直是 交叉軸。 對於 Column 來說, 垂直是主軸。水平是 交叉軸 把 children 放到 主軸 的哪個位置 。 如果要驗證這個屬性,記住把 mainAxisSize 設定成 MainAxisSize.max ,

取值說明樣式圖片(Rowd 的demo)
MainAxisAlignment.start(預設值)把 children 放到主軸的頭部Flutter控制元件--Row、Column和Stack
MainAxisAlignment.center 把 children 放到主軸的中間Flutter控制元件--Row、Column和Stack
MainAxisAlignment.end 把 children 放到主軸的尾部 Flutter控制元件--Row、Column和Stack
MainAxisAlignment.spaceAround 將主軸方向空白區域均分,使得children之間空間相等,但是首尾 childre 的空白部分為一半 Flutter控制元件--Row、Column和Stack
MainAxisAlignment.spaceBetween 將主軸方向空白區域均分,使得children之間空間相等,但是首尾childre靠近收尾,沒有空細逢 Flutter控制元件--Row、Column和Stack
MainAxisAlignment.spaceEvenly 將主軸方向空白區域均分,使得children之間空間相等,包括首尾childre Flutter控制元件--Row、Column和Stack

2.2 mainAxisSize

也就是來規定自己( Row 或者 Column )的大小。

  • MainAxisSize.min : 主軸方向,包裹住 childre 即可。相當於 android 中的 wrap_content
  • MainAxisSize.max(預設值) : 主軸方向,鋪滿 ( Row 或者 Column )的父 Widget 的大小。 相當於 android 中的 match_parent

2.3 crossAxisAlignment (交叉軸)跟主軸垂直的一個軸

交叉軸 顧名思義: 就是 跟 主軸 垂直的 一個軸 對於 Row 。交叉軸 是 在垂直。對於 Column,交叉軸 是水平 。下面還是 以 Row 舉個例子

取值 說明 圖片demo(Row)
CrossAxisAlignment.start 把 children 放到交叉軸的頭部 Flutter控制元件--Row、Column和Stack
CrossAxisAlignment.end 把 children 放到交叉軸的尾部 Flutter控制元件--Row、Column和Stack
CrossAxisAlignment.center 把 children 放到交叉軸的中間 Flutter控制元件--Row、Column和Stack
CrossAxisAlignment.stretch 讓children填滿交叉軸方向 無(沒有測試出來,控制元件 找不到了)
CrossAxisAlignment.baseline 讓children 於 baseline 對齊,如果主軸是垂直的,那麼這個值是當作開始 ,設定了此 屬性 textBaseline 不能為 null Flutter控制元件--Row、Column和Stack

2.4 textDirection

children 在 主軸 怎樣排列。 正方向排列還是反方向排列

Row
  • TextDirection.ltr : 表示在水平方向(主軸)。由左到右 , 左為頭 , 右為尾
  • TextDirection.rtl :表示在水平方向(主軸)。由右到左 , 右為頭 , 左為尾
Column
  • TextDirection.ltr : 表示在垂直方向(主軸)。由上到下 , 上為頭 , 下為尾
  • TextDirection.rtl :表示在垂直方向(主軸)。由下到上 , 下為頭 ,上為尾

2.5 verticalDirection

children 在 交叉軸 怎樣排列。 正方向排列還是反方向排列

Row
  • VerticalDirection.down : 表示在垂直方向(交叉軸)。由上到下 , 上為頭 , 下為尾
  • VerticalDirection.up :表示在垂直方向(交叉軸)。由下到上 , 下為頭 , 上為尾
Column
  • VerticalDirection.down : 表示在水平方向(交叉軸)。由左到右 , 左為頭 , 右為尾
  • TextDirection.rtl :表示在水平方向(交叉軸)。由右到左 , 右為頭 , 左為尾

二 Stack

取代線性佈局 (和Android中的LinearLayout相似,但是我感覺怎麼這麼像 FrameLayout 呢?),Stack允許子 widget 堆疊, 你可以使用 Positioned 來定位他們相對於Stack的上下左右四條邊的位置。Stacks是基於Web開發中的絕度定位(absolute positioning )佈局模型設計的。用於將多個childs相對於其框的邊緣定位,多用於以簡單方式重疊children

2.1 屬性

  • alignment: 預設值。AlignmentDirectional.topStart ( AlignmentDirectional(-1.0, -1.0) )。 表示從左上角開始排 children
  • textDirection: 文字方向 , children 的流動方向
  • overflow: 表示 超過的部分是否裁剪掉 Overflow.visible 不剪掉。 Overflow.clip 減掉
  • fit: 讓 children 怎樣填充 Stack 。
    • StackFit.passthrough 不改變子節點約束 也就是說 children 是多大就是多大
    • StackFit.expand 子節點最大可能的佔用空間 ,讓 children 的大小 擴大到 Stack 的大小
    • StackFit.loose:放開了子節點寬高的約束,可以讓子節點從0到最大尺寸

三 demo圖片

Flutter控制元件--Row、Column和Stack

demo 程式碼

import 'package:flutter/material.dart';

class LayoutDemo extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return Scaffold(
      appBar: AppBar(
        title: Text("row"),
        centerTitle: true,
      ),
      body: RowDemo(),
    );
  }
}

class RowDemo extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    final _list = <Widget>[
      RaisedButton(
        disabledColor: Colors.red,
        child: Text("兒子1"),
      ),
      Text("兒子2"),
      Text("兒子3"),
      Text("兒子4"),
      Text("兒子5"),
    ];
    return Column(
      children: <Widget>[
        SizedBox(
          height: 30,
        ),
        Container(
          color: Colors.grey,
          child: Row(
            // 主軸(main axis)
            // 把 children 放到 Column 主軸 的哪個位置
            //  end : 尾部, start :頭部, center : 中間 ,spaceBetween:在 children 之間均勻地放置 空間 ,spaceAround : 每個 children
            mainAxisAlignment: MainAxisAlignment.start,

            // 此 Row 的寬度。預設是 MainAxisSize.max
            //          MainAxisSize.min 是 包裹 children 的高度 即可  。android 中 相當於 wrap_content
            //          MainAxisSize.max 是 鋪滿 Row 的父 Widget 的寬度  。android 中 相當於 match_parent
            //  如果設定成 MainAxisSize.min 。 那麼 mainAxisAlignment 屬性相當於無效。 因為是包裹 children
            mainAxisSize: MainAxisSize.max,
            // 交叉軸(cross axis)
            // 把 children 放到 Column 主軸 的哪個位置
            // end : 尾部, start :頭部, center : 中間 ,
            crossAxisAlignment: CrossAxisAlignment.start,
            // children 在主軸 的排列順序
            textDirection: TextDirection.ltr,
            // children 在 交叉軸 的排列順序
            verticalDirection: VerticalDirection.down,
            children: _list,
          ),
        ),
        SizedBox(
          height: 30,
        ),
        SizedBox(
            width: 200,
            height: 200,
            child: Stack(
              alignment: AlignmentDirectional.topStart,
//            alignment:   AlignmentDirectional(-1.0, -1.0),
              fit: StackFit.loose,
              overflow: Overflow.visible,
              children: <Widget>[
                Container(
                  color: Colors.black,
                  height: 200,
                  width: 200,
                ),
                Container(
                  color: Colors.deepPurple,
                  height: 100,
                  width: 100,
                ),
                Container(
                  color: Colors.green,
                  height: 50,
                  width: 50,
                ),
              ],
            )),
      ],
    );
  }
}

複製程式碼

相關文章