Expanded 子元件


在〈Row 與 Column〉的範例中,對每個 Container 設定了 widthheight,自行設定寬高必須小心,元件別超出了 RowColumn 分到的空間,否則會發生 OVERFLOW 的錯誤。例如:

import 'package:flutter/material.dart';

void main() => runApp(
    Column(
      children: [
        Container(
          color: Colors.blue,
          width:100,
          height: 500,
        ),
        Container(
          color: Colors.yellow,
          width:100,
          height: 500,
        ),
      ],
    )
);

在上面的例子中,因為根元件就是 Column,它分配到的空間就是螢幕尺寸(依你的父元件而定,分配到的空間不見得就是螢幕尺寸),RowColumn 預設並不約束子元件的尺寸,因此子元件會依各自尺寸設定繪製,然而空間不足以繪製全部的子元件,此時就會出現以下的畫面:

Expanded 子元件

比較好的方式,是元件可以適應分配到的空間自行調整尺寸,這時可以使用 Expanded,例如:

import 'package:flutter/material.dart';

void main() => runApp(
  Column(
    children: [
      Expanded(
        child: Container(
          color: Colors.blue,
          width:100,
        ),
      ),
      Expanded(
        child: Container(
          color: Colors.yellow,
          width:100,
        )
      ),
    ],
  )
);

這個範例使用了 Column,在不設定 Container 的高度下,Expanded 會自動擴展子元件,令其高度可填滿分配到的空間,執行結果如下:

Expanded 子元件

Expanded 有個 flex 特性作為彈性係數,用來衡量子元件在 main axis 上可佔有空間量,預設是 1,以上例來說,因為每個子元件的 flex 是 1,就平均分配了高度,如果是以下:

import 'package:flutter/material.dart';

void main() => runApp(
  Column(
    children: [
      Expanded(
        child: Container(
          color: Colors.red,
          width:100,
        ),
      ),
      Expanded(
        child: Container(
          color: Colors.yellow,
          width:100,
        ),
        flex: 2
      ),
      Expanded(
        child: Container(
          color: Colors.green,
          width:100,
        )
      ),
    ],
  )
);

因為第二個子元件的 flex 是 2,其他子元件是 1,第二個子元件就佔有 2/4 的高度:

Expanded 子元件

flex 若設為 null 或 0,表示子元件自行決定尺寸,例如,決定上下元件尺寸,中間自動填滿:

import 'package:flutter/material.dart';

void main() => runApp(
  Column(
    children: [
      Expanded(
        child: Container(
          color: Colors.red,
          width:100,
          height: 100
        ),
        flex: 0
      ),
      Expanded(
        child: Container(
          color: Colors.yellow,
          width:100,
        ),
      ),
      Expanded(
        child: Container(
          color: Colors.green,
          width:100,
          height: 100
        ),
        flex: 0
      ),
    ],
  )
);

Expanded 子元件

Expanded 展開的是 child 元件可獲得的空間,至於獲得的空間如何使用,就是 child 參考的 Widget 自己要決定的,例如:

import 'package:flutter/material.dart';

void main() => runApp(
  Column(
    children: [
      Expanded(
        child: Container(
          child: Image.network('https://openhome.cc/Gossip/images/caterpillar_small_front.jpg', fit: BoxFit.fill,),
          color: Colors.red,
        ),
        flex: 2
      ),
      Expanded(
        child: Container(
          child: Image.network('https://openhome.cc/Gossip/images/caterpillar_small_front.jpg', repeat: ImageRepeat.repeatX,),
          color: Colors.yellow,
        ),
        flex: 3
      ),
      Expanded(
        child: Container(
          child: Image.network('https://openhome.cc/Gossip/images/caterpillar_small_front.jpg'),
          color: Colors.green,
        ),
        flex: 2
      ),
    ],
  )
);

執行結果如下:

Expanded 子元件