Skip to content

avoid_flexible_outside_flex

v0.4.0 Warning Widget Best Practices

Flags a Flexible or Expanded that is not a direct child of a Row, Column or Flex.

Both widgets work by handing a flex factor to the parent’s layout protocol. A non-flex parent — Container, Padding, Center, SizedBox — ignores it. Nothing throws at build time; the widget simply has no effect, which is why this is worth catching at lint time rather than by staring at the tree.

This rule is in the core preset, so it is on with preset: core and every preset above it. No configuration.

See also: Flexible | Row

The usual way in is wrapping for padding after the layout already worked:

Column(
children: [
// Padding is not a Flex, so Expanded does nothing here
Padding(
padding: const EdgeInsets.all(8),
child: Expanded(child: Text('Body')),
),
],
)

Keep Expanded next to the Column and move the wrapper inside it:

Column(
children: [
Expanded(
child: Padding(
padding: const EdgeInsets.all(8),
child: Text('Body'),
),
),
],
)

Nesting a flex inside a flex is fine — each Expanded just has to sit directly in one of them:

// Don't — Center swallows the flex factor
final bad = Row(
children: [
Center(child: Flexible(child: Text('Title'))),
],
);
// Do
final good = Row(
children: [
Flexible(child: Center(child: Text('Title'))),
],
);

A Flexible returned bare from a helper or built outside any flex parent is reported too — there is no layout to be flexible in:

// Don't
Widget spacerBar() => Expanded(child: Container());
// Do — return the child, and let the caller wrap it
Widget spacerBar() => Container();
many_lints.yaml
rules:
avoid_flexible_outside_flex: false

To keep the rule on but skip certain paths, use per-rule exclude.