使用 Container


在〈Widget 概覽〉中使用過 Container,或許你用過其他 UI 框架,當中也有名為 Container 的元件,通常(實現了 Composite 模式)用來管理一組元件,不過 Flutter 中的 Container 跟它們不同,只容納「一個」元件。

可以把 Flutter 中的 Container 想成是個盒子,本身也是個 WidgetContainer 直接繼承 StatelessWidget

Widget > StatelessWidget > Container

Container 本身其實也是個可視元件,例如,來個全紅的 Container,底下這個範例執行後,整個螢幕會被紅色填滿:

import 'package:flutter/material.dart';

void main() => runApp(
  Container(
    color: Colors.red,
  )
);

Container 裏頭只能放一個 Widget,使用 Container 的目的,通常就是為了對該 Widget 做些裝飾、排列,設定尺寸、約束、邊框(border)、邊距(margin)或墊充(padding)。

有關於邊距、邊框、墊充,官方網站〈Layouts in Flutter〉中有張圖:

使用 Container

例如,來建立一個最大 300 x 300 的 Container,包含邊框、墊充等設定:

import 'package:flutter/material.dart';

void main() => runApp(
  Center(
    child: Container(
      child: Container(color: Colors.red), // 內裝背景紅色元件
      alignment: Alignment.center,         // 內裝元件置中對齊
      decoration: BoxDecoration(           // 裝飾內裝元件
        color: Colors.green,                               // 綠色背景
        border: Border.all(width: 10, color: Colors.blue), // 藍色邊框
      ),
      padding: const EdgeInsets.all(20),   // 墊充
      constraints: BoxConstraints(         // 容器的尺寸約束
        maxWidth: 300,
        maxHeight: 300,
      ),
    )
  )
);

因為作為根的 Widget 會被填滿整個螢幕,為了令 Containerconstraints 能起作用,將之置於 Center 中,constraints 設定的大小會包含邊框、墊充。

範例中的內裝元件只是另一個設定為紅色的 Container,沒有設定 constraintsdecorationpadding 等,因此預設會填滿整個 Container,執行結果如下:

使用 Container

Containerpaddingmargin,都是使用 EdgeInsetsGeometry 實例來設定,EdgeInsets 提供了一些便捷的 static 方法,all 表示四邊都設定相同的值,其他還有 EdgeInsets.onlyEdgeInsets.symmetric 等,可以查詢一下 EdgeInsets 的 API 文件,來認識一下各設定之意義。

Container 還有個特別功能,可以透過 transform 指定矩陣運算來變形。例如依序繞 X、Y、Z 軸旋轉後平移:

import 'package:flutter/material.dart';

void main() {
  Matrix4 m = Matrix4.translationValues(-50, 150, 0);
  m.multiply(Matrix4.rotationZ(-.5));  // 單位:徑度
  m.multiply(Matrix4.rotationY(1));
  m.multiply(Matrix4.rotationX(1));

  runApp(
    Center(
      child: Container(
        child: Text('哈囉,世界!',
          textDirection: TextDirection.ltr,
          style: TextStyle(fontSize: 40),
        ), // 內裝元件
        alignment: Alignment.center,
        decoration: BoxDecoration(
          color: Colors.green,
        ),
        constraints: BoxConstraints(
          maxWidth: 300,
          maxHeight: 300,
        ),
        transform: m,
      )
    )
  );
}

座標原點是螢幕左上角,往右為正 X 軸,往下為正 Y 軸,深度為正 Z 軸,也就是採用的是右手座標Matrix4 的運算採用的是後乘,簡單來說,想想看你想寫繞 X、Y、Z 軸旋轉後平移的矩陣公式,會是這麼寫:

[平移] * [旋轉 Z] * [旋轉 Y] * [旋轉 X] * [目標]

程式碼的撰寫時相乘順序就是依序這麼寫,範例的執行結果如下:

使用 Container