This tutorial explains what is IntrinsicWidth
widget in Flutter along with the usage examples.
IntrinsicWidth
is a widget used to size its child to its maximum intrinsic width. It can be useful if the available width is unlimited, but you want to set the size of a widget to its intrinsic width.
Using IntrinsicWidth
Let's start with an example where there is a Column
widget with the crossAxisAlignment
sets to stretch
. It has two Container
widgets as its children with the second container is wrapped as the child of an Expanded
widget. That means the height of the second container will be expanded to the maximum space. For the width of the Column
, because it uses CrossAxisAlignment.stretch
, it will also be expanded to the maximum space.
Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Container(
width: 200,
height: 100,
color: Colors.teal,
),
Expanded(
child: Container(
width: 100,
height: 100,
color: Colors.red,
),
),
],
)
Output:
What if you want to set the width of a widget to be its intrinsic width. You can wrap it as the child of an IntrinsicWidth
widget. Below is the constructor.
IntrinsicWidth({ Key key, this.stepWidth, this.stepHeight, Widget child })
Here's a basic usage example which only passes the child
argument.
IntrinsicWidth(
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Container(
width: 200,
height: 100,
color: Colors.teal,
),
Expanded(
child: Container(
width: 100,
height: 100,
color: Colors.red,
),
),
],
),
)
Output:
The above output shows that the width is set to the width of the children with maximum width which is the first Container
whose width is 200.
In the next example, we are going to set the stepWidth
argument to 150. That causes the width of the child to be the smallest value which is a multiple of 150.
IntrinsicWidth(
stepWidth: 150,
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Container(
width: 200,
height: 100,
color: Colors.teal,
),
Expanded(
child: Container(
width: 100,
height: 100,
color: Colors.red,
),
),
],
),
)
Output:
Next, we are going to set the stepHeight
argument to 100. In the previous examples where the stepHeight
is not passed, the height of the child expands to fill the maximum space. By passing stepWidth
argument, the height of the child will be set to a minimum value that's a multiplication of the stepHeight
.
IntrinsicWidth(
stepHeight: 100,
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Container(
width: 200,
height: 100,
color: Colors.teal,
),
Expanded(
child: Container(
width: 100,
height: 100,
color: Colors.red,
),
),
],
),
)
Output:
Using IntrinsicWidth
is considered expensive because of the need to add a speculative layout pass before the final layout phase. In the worst case, the depth of the tree can be O(N²). Therefore, the usage of IntrinsicWidth
should be avoided if possible. For the above cases, you can consider using a widget that can be used to add constraints to the child, such as SizedBox
or ConstrainedBox
.
SizedBox(
width: 300,
height: 200,
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Container(
width: 200,
height: 100,
color: Colors.teal,
),
Expanded(
child: Container(
width: 100,
height: 100,
color: Colors.red,
),
),
],
),
)
Output:
Keep in mind that the constraints applied by IntrinsicWidth
widget must comply with the constraints from the parent. Therefore, the child's width can be less than its intrinsic width if the maximum width constraint from the parent is not large enough. Likewise, the child's width can be larger than its intrinsic width if the minimum width constraint is larger than the intrinsic width.
IntrinsicWidth
Parameters
Key key
: The widget's key.Widget child
: The widget under this widget in tree, whose width will be set to its intrinsic width.double stepWidth
: If non-null, force the width of the child to be multiple of this value. If null or 0.0, the width of the child is the same as its maximum intrinsic width.double stepHeight
: If non-null, force the height of the child to be multiple of this value. If null or 0.0, the height of the child will not be constrained.
Full Code
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Woolha.com Flutter Tutorial',
home: _IntrinsicWidthExample(),
);
}
}
class _IntrinsicWidthExample extends StatelessWidget {
final Widget column = Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Container(
width: 200,
height: 100,
color: Colors.teal,
),
Expanded(
child: Container(
width: 100,
height: 100,
color: Colors.red,
),
),
],
);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Woolha.com Flutter Tutorial'),
),
// body: column,
body: IntrinsicWidth(
stepWidth: 150,
stepHeight: 100,
child: column,
),
// body: SizedBox(
// width: 300,
// height: 200,
// child: column,
// ),
);
}
}
Summary
That's how to use IntrinsicWidth
in Flutter which is used to set the width of a widget to its intrinsic width. You can also pass stepWidth
and/or stepHeight
arguments to force the width and/or the height of the child to be a multiplication of the given values.
You can also read about:
IntrinsicHeight
: a widget used to set the height of its child to the child's intrinsic height.UnconstrainedBox
: a widget that imposes no constraints on its child.ConstrainedBox
: a widget that imposes additional constraints on its child.SizedBox
: a box with a specified size.