-
-
Notifications
You must be signed in to change notification settings - Fork 513
Woven
The Woven layout is one of the four types of Image lists, showcased in Material Design.
It is implemented as a specific GridDelegate
and can be used with the Flutter built-in widgets called SliverGrid
and GridView
.
GridView.custom(
gridDelegate: SliverWovenGridDelegate.count(
crossAxisCount: 2,
mainAxisSpacing: 8,
crossAxisSpacing: 8,
pattern: [
WovenGridTile(1),
WovenGridTile(
5 / 7,
crossAxisRatio: 0.9,
alignment: AlignmentDirectional.centerEnd,
),
],
),
childrenDelegate: SliverChildBuilderDelegate(
(context, index) => Tile(index: index),
),
);
This SliverWovenGridDelegate
has two constructors.
This constructor is used to divide the cross axis by a specific number, whatever the available size is.
You can control this through the crossAxisCount
parameter.
Use this constructor when you want to always have the same number of division in the cross axis extent.
This constructor is used to set a maximum extent for each division in the cross axis.
You can control this through the maxCrossAxisExtent
parameter.
For example, in the case of a vertical 408px wide grid and without spacings between tiles, if you set the maxCrossAxisExtent
to 204, the grid will have two 204px wide columns. If you set the maxCrossAxisExtent
to 150, it will have three 136px wide columns (because the layout will try to give has mush space to each column without exceeding 150px).
Use this constructor when you want to show more or less items in the cross axis extent depending on the available space.
The pattern is a list of WovenGridTile
.
Each tile indicates:
- Its
aspectRatio
, which is the cross axis extent of the tile divided by its main axis extent. - Its
crossAxisRatio
, a number between 0 and 1 (defaults to 1), which indicates the ratio between the available space in the cross axis and the cross axis extent of the tile. - Its
alignment
, which determine how the tile is aligned within its available space when thecrossAxisRatio
is less than 1.
The grid below can be obtained with the following pattern with a spacing in both directions set to 4:
pattern: [
WovenGridTile(1),
WovenGridTile(
5 / 7,
crossAxisRatio: 0.9,
alignment: AlignmentDirectional.centerEnd,
),
],
The tiles 0 and 3 are defined by
WovenGridTile(1)
The tiles 1 and 2 are defined by
WovenGridTile(
5 / 7,
crossAxisRatio: 0.9,
alignment: AlignmentDirectional.centerEnd,
),
In the case of a 204px wide grid this is how we can compute the height and width of these tiles:
- The grid is divided in two 100px wide columns with a spacing of 4px between the columns.
- The tiles 0 and 3 have a height and width equals to 100px (1.0 * 100).
- The tiles 1 and 2 have a width equals to 90px (0.9 * 100) and a height equals to 126 (90 * 7 / 5).
- The tiles 1 and 2 have an alignment set to
AlignmentDirectional.centerEnd
.
The arrow represents the direction used by the alignment to place the tiles:
- In the first row we have a left-to-right direction.
- In the second row we have a right-to-left direction.
That's why in the second row the
end
represents the left side.
To respect the Material Guidelines, you can also set a parameter called tileBottomSpace
which adds a specifc amount of space below the tile. This space is intended to be used for displaying a text describing the tile. If you use this feature, your widget should have the same amount of pixels for this part.
This layout uses the ambient TextDirection
to know if it should create the grid from left-to-right
or right-to-left.
Just add a Directionality
widget above the GridView
(or CustomScrollView
) to set the order in which the tiles are rendered.
Directionality(
textDirection: TextDirection.rtl,
child: GridView.custom(
gridDelegate: SliverWovenGridDelegate.count(
crossAxisCount: 2,
mainAxisSpacing: 8,
crossAxisSpacing: 8,
pattern: [
WovenGridTile(1),
WovenGridTile(
5 / 7,
crossAxisRatio: 0.9,
alignment: AlignmentDirectional.centerEnd,
),
],
),
childrenDelegate: SliverChildBuilderDelegate(
(context, index) => Tile(index: index),
),
),
),