Flutter Widgets 之 Expanded和Flexible

注意:無特殊說明,Flutter版本及Dart版本如下:

  • Flutter版本: 1.12.13+hotfix.5
  • Dart版本: 2.7.0

Expanded和Flexible是控制Row、Column、Flex的子控件如何佈局的控件,Expanded和Flexible可以擴張填滿主軸剩餘空間,如何確認主軸和交叉軸可以查看Flutter Widgets 之 Row和Column,這篇文章詳細介紹了主軸和交叉軸。

Expanded和Flexible的區別

首先看一下Expanded和Flexible的構造函數:

區別如下

  • Expanded 繼承自Flexible。
  • Flexible 中fit參數默認是FlexFit.loose,而Expanded固定爲FlexFit.tight

因此如果在使用Flexible時,設置fitFlexFit.tight,Flexible和Expanded就一模一樣了,代碼如下:

Flexible(
	fit: FlexFit.tight,
	...
)

因此Expanded和Flexible的區別就是FlexFit.tightFlexFit.loose的區別:

  • tight:必須(強制)填滿剩餘空間。
  • loose:儘可能大的填滿剩餘空間,但是可以不填滿。

看下面2個例子就能看出其中的區別:

Row(
      children: <Widget>[
        Container(
          color: Colors.blue,
          height: 50,
          width: 100,
        ),
        Flexible(
            child: Container(
              color: Colors.red,
              height: 50,
            )
        ),
        Container(
          color: Colors.blue,
          height: 50,
          width: 100,
        ),
      ],
    )

效果如圖:

中間的紅色的控件是Container,此時填滿了剩餘空間,我們給Container添加子控件Text,代碼如下:

Row(
      children: <Widget>[
        Container(
          color: Colors.blue,
          height: 50,
          width: 100,
        ),
        Flexible(
            child: Container(
              color: Colors.red,
              height: 50,
			  child: Text('Container',style: TextStyle(color: Colors.white),),
            )
        ),
        Container(
          color: Colors.blue,
          height: 50,
          width: 100,
        ),
      ],
    )

效果圖:

神奇出現了,此時沒有填滿剩餘空間,我們再給Container添加對齊方式,代碼如下:

Row(
      children: <Widget>[
        Container(
          color: Colors.blue,
          height: 50,
          width: 100,
        ),
        Flexible(
            child: Container(
              color: Colors.red,
              height: 50,
			  alignment: Alignment.center,
			  child: Text('Container',style: TextStyle(color: Colors.white),),
            )
        ),
        Container(
          color: Colors.blue,
          height: 50,
          width: 100,
        ),
      ],
    )

效果圖:

此時又填滿剩餘空間,大家是否還記得Container控件的大小是調整的嗎?Container默認是適配子控件大小的,但當設置對齊方式時Container將會填滿父控件,在Flutter Widgets 之 Container中已經詳細介紹,因此是否填滿剩餘空間取決於子控件是否需要填滿父控件。

如果把Flexible中子控件由Container改爲OutlineButton,代碼如下:

Row(
      children: <Widget>[
        Container(
          color: Colors.blue,
          height: 50,
          width: 100,
        ),
        Flexible(
          child: OutlineButton(
            child: Text('OutlineButton'),
          ),
        ),
        Container(
          color: Colors.blue,
          height: 50,
          width: 100,
        ),
      ],
    )

OutlineButton正常情況下是不充滿父控件的,因此最終的效果應該是不填滿剩餘空間,效果如圖:

如果想讓OutlineButton填滿剩餘空間只需將Flexible改爲Expanded,代碼如下:

Row(
      children: <Widget>[
        Container(
          color: Colors.blue,
          height: 50,
          width: 100,
        ),
        Expanded(
          child: OutlineButton(
            child: Text('OutlineButton'),
          ),
        ),
        Container(
          color: Colors.blue,
          height: 50,
          width: 100,
        ),
      ],
    )

效果如圖:

到這裏有沒有感覺FlexFit.loose很雞肋啊,如果不想填滿剩餘空間直接不使用這個組件不就可以了嗎,既然使用ExpandedFlexible就說明想填滿剩餘空間,可能是我們的需求還沒有那麼變態吧。

建議:如果想填滿剩餘空間直接使用Expanded更方便。

這裏總結下Expanded和Flexible的區別:

  • Expanded:強制填滿剩餘空間
  • Flexible:不強制填滿剩餘空間,是否填滿剩餘空間取決於子控件是否需要填滿父控件。

flex

參數flex表示權重(類似於Android中的weight),在Column中添加3個子控件,flex分別爲1、2、3,代碼如下:

Column(
      children: <Widget>[
        Expanded(
          flex: 1,
          child: Container(
            color: Colors.blue,
            alignment: Alignment.center,
            child: Text('1 Flex/ 6 Total',style: TextStyle(color: Colors.white),),
          ),
        ),
        Expanded(
          flex: 2,
          child: Container(
            color: Colors.red,
            alignment: Alignment.center,
            child: Text('2 Flex/ 6 Total',style: TextStyle(color: Colors.white),),
          ),
        ),
        Expanded(
          flex: 3,
          child: Container(
            color: Colors.green,
            alignment: Alignment.center,
            child: Text('3 Flex/ 6 Total',style: TextStyle(color: Colors.white),),
          ),
        ),
      ],
    )

效果如圖:

子控件佔比 = 當前子控件flex/所有子控件flex只和。

更多相關閱讀:

如果這篇文章有幫助到您,希望您關注我的公衆號,謝謝。

發佈了138 篇原創文章 · 獲贊 86 · 訪問量 32萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章