Flutter中Expanded 和 Flexible 有什么区别?

991 阅读2分钟

Expanded 和 Flexible 都是Flutter中的布局Widget,它们被用来在行(Row)、列(Column)和弹性布局(Flex)中控制子Widget是如何弹性地占据空间的。尽管它们非常相似,但它们之间有一个关键的区别:

Expanded

Expanded 是一种特殊类型的Flexible,其flex属性默认值为1,fit属性也默认为FlexFit.tight。这意味着使用Expanded包裹的子Widget会填满父Widget余下的可用空间。

Row(
  children: <Widget>[
    Expanded(
      child: Container(color: Colors.red), // 这个Widget会扩展填满Row的剩余空间
    ),
    Container(width: 100, color: Colors.blue), // 这个Widget的宽度固定为100
  ],
)

Flexible

Flexible 允许子Widget有更多的灵活性。通过flex属性,Flexible可以让子Widget根据其大小来分配父Widget中的闲置空间。Flexiblefit属性可以设置为FlexFit.looseFlexFit.tight。使用FlexFit.loose,子Widget可以按照自己的大小来显示,而不用填满剩余空间。FlexFit.tight(等同于Expanded)会强制子Widget扩展以填满剩余空间。

Row(
  children: <Widget>[
    Flexible(
      flex: 2,
      child: Container(color: Colors.red),
    ),
    Flexible(
      flex: 1,
      child: Container(color: Colors.blue),
    ),
  ],
)

在上面的代码中,红色容器将占父容器可用空间的2/3,蓝色容器将占1/3。

使用案例

当你希望子Widget只是占据其自身需要的空间时,应使用Flexible。例如,在创建一个水平布局的Row时,如果你想让两个子Widget之间有一段空间,并且让其中一个子Widget(如一个文本)尽量使用它的自然大小,那么你应该选择Flexible

Row(
  children: <Widget>[
    Flexible(
      child: Container(
        color: Colors.red,
        child: Text('Short text'),
      ),
    ),
    SizedBox(width: 20), // 间隔空间
    Container(
      width: 100,
      color: Colors.blue,
      child: Text('Fixed width text'),
    ),
  ],
)

在上述例子中,第一个文本容器只会尽量使用自己内容的宽度,后面跟着一个特定宽度的蓝色容器和一定宽度的间隔。

相反,如果你使用Expanded,它将强制第一个子Widget扩展填满除了蓝色固定宽度子Widget和间隔之外的剩余空间。

记住,FlexibleExpanded更灵活,它允许你的Widget在保持其自然大小的同时享有一定的弹性空间。但如果你明确期望子Widget强制填满所有剩余空间,则应选择Expanded

最后,当决定是否使用Expanded还是Flexible时,考虑周围布局的上下文和子Widget间的空间分配。对于布局来说,清晰和一致比简单粗暴地填满空间更重要。通过适当的测试和布局细节调整,你可以创建出与你的应用交互设计相协调的界面。