-
-
Notifications
You must be signed in to change notification settings - Fork 512
Masonry
The Masonry layout is one of the four types of Image lists, showcased in Material Design.
Like the built-in grid component, there is a MasonryGridView
(the equivalent of the GridView
widget):
MasonryGridView.count(
crossAxisCount: 4,
mainAxisSpacing: 4,
crossAxisSpacing: 4,
itemBuilder: (context, index) {
return Tile(
index: index,
extent: (index % 5 + 1) * 100,
);
},
),
There is also a sliver called SliverMasonryGrid
(the equivalent of the SliverGrid
):
CustomScrollView(
slivers: [
SliverMasonryGrid.count(
crossAxisCount: 4,
mainAxisSpacing: 4,
crossAxisSpacing: 4,
itemBuilder: (context, index) {
return Tile(
index: index,
extent: (index % 5 + 1) * 100,
);
},
),
],
),
This SliverMasonryGrid
has two main named constructors which you can also use with the MasonryGridView
.
The other constructors can be used if you want a more specific behavior.
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.
All constructors have a mainAxisSpacing
and a crossAxisSpacing
parameters.
The mainAxisSpacing
define the amount of pixels between two tiles in the main axis.
The crossAxisSpacing
define the amount of pixels between two tiles in the cross axis.
For example, in a vertical grid, the columns are separated by a space with a value of crossAxisSpacing
and each tile is separated from the next one within the same column by a space with a value of mainAxisSpacing
.
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 MasonryGridView
(or CustomScrollView
) to set the order in which the tiles are rendered.
Directionality(
textDirection: TextDirection.rtl,
child: MasonryGridView.count(
crossAxisCount: 4,
mainAxisSpacing: 4,
crossAxisSpacing: 4,
itemBuilder: (context, index) {
return Tile(
index: index,
extent: (index % 5 + 1) * 100,
);
},
),
),
Each time the grid is scrolled, the GridDelegate
is called to compute the index of the visible tiles. It's quite performant for a regular grid to compute them for any scroll offset because the size of each tile is fixed.
The masonry layout, let's you provide tiles with dynamic main axis extents. In order to compute the index of the visible tiles, we would have to compute all the sizes of the tiles from the beginning, and this for each scroll interaction. This is not possible to have a performant way of doing this with the GridDelegate
. That's why this layout is not implemented as a GridDelegate
and has its own MasonryGridView
widget.