注意:無(wú)特殊說(shuō)明,F(xiàn)lutter版本及Dart版本如下:
- Flutter版本: 1.12.13+hotfix.5
- Dart版本: 2.7.0
Expanded和Flexible是控制Row、Column、Flex的子控件如何布局的控件,Expanded和Flexible可以擴(kuò)張?zhí)顫M主軸剩余空間,如何確認(rèn)主軸和交叉軸可以查看Flutter Widgets 之 Row和Column,這篇文章詳細(xì)介紹了主軸和交叉軸。
Expanded和Flexible的區(qū)別
首先看一下Expanded和Flexible的構(gòu)造函數(shù):
區(qū)別如下
- Expanded 繼承自Flexible。
- Flexible 中
fit參數(shù)默認(rèn)是FlexFit.loose,而Expanded固定為FlexFit.tight。
因此如果在使用Flexible時(shí),設(shè)置fit為FlexFit.tight,F(xiàn)lexible和Expanded就一模一樣了,代碼如下:
Flexible(
fit: FlexFit.tight,
...
)
因此Expanded和Flexible的區(qū)別就是FlexFit.tight和FlexFit.loose的區(qū)別:
- tight:必須(強(qiáng)制)填滿剩余空間。
- loose:盡可能大的填滿剩余空間,但是可以不填滿。
看下面2個(gè)例子就能看出其中的區(qū)別:
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,此時(shí)填滿了剩余空間,我們給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,
),
],
)
效果圖:
神奇出現(xiàn)了,此時(shí)沒(méi)有填滿剩余空間,我們?cè)俳oContainer添加對(duì)齊方式,代碼如下:
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,
),
],
)
效果圖:
此時(shí)又填滿剩余空間,大家是否還記得Container控件的大小是調(diào)整的嗎?Container默認(rèn)是適配子控件大小的,但當(dāng)設(shè)置對(duì)齊方式時(shí)Container將會(huì)填滿父控件,在Flutter Widgets 之 Container中已經(jīng)詳細(xì)介紹,因此是否填滿剩余空間取決于子控件是否需要填滿父控件。
如果把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正常情況下是不充滿父控件的,因此最終的效果應(yīng)該是不填滿剩余空間,效果如圖:
如果想讓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,
),
],
)
效果如圖:
到這里有沒(méi)有感覺(jué)FlexFit.loose很雞肋啊,如果不想填滿剩余空間直接不使用這個(gè)組件不就可以了嗎,既然使用Expanded和Flexible就說(shuō)明想填滿剩余空間,可能是我們的需求還沒(méi)有那么變態(tài)吧。
<font color='red'>建議:如果想填滿剩余空間直接使用Expanded更方便。</font>
這里總結(jié)下Expanded和Flexible的區(qū)別:
- Expanded:強(qiáng)制填滿剩余空間
- Flexible:不強(qiáng)制填滿剩余空間,是否填滿剩余空間取決于子控件是否需要填滿父控件。
flex
參數(shù)flex表示權(quán)重(類似于Android中的weight),在Column中添加3個(gè)子控件,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),),
),
),
],
)
效果如圖:
<font color='red'>子控件占比 = 當(dāng)前子控件flex/所有子控件flex只和。</font>
更多相關(guān)閱讀:
- Flutter系列文章總覽
- Flutter Widgets 之 Container
- Flutter Widgets 之 AnimatedList
- Flutter Widgets 之 SliverAppBar