-
-
Notifications
You must be signed in to change notification settings - Fork 510
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[FR] Dynamic pattern builder #351
Comments
For anyone that could be slightly interested in how the same could be achieved without the suggested implementation, this is how I've done it, it's not pretty: StaggeredGrid.count implementation/// Draws a staggered grid of images, where the pattern is based
/// on the amount of images to fill the grid at all times.
///
/// They will be alternating depending on the current index of the images.
///
/// For example, if there are 4 images in the last segment, this will be drawn:
/// ┌─────┐┌─┐┌─┐
/// │ │└─┘└─┘
/// │ │┌────┐
/// └─────┘└────┘
///
/// If there are 3 images in the last segment, this will be drawn:
/// ┌─────┐┌────┐
/// │ │└────┘
/// │ │┌────┐
/// └─────┘└────┘
///
/// If there are 2 images in the last segment, this will be drawn:
/// ┌─────┐┌─────┐
/// │ ││ │
/// └─────┘└─────┘
///
/// If there is 1 image in the last segment, this will be drawn:
/// ┌──────────┐
/// │ │
/// └──────────┘
class StaggeredGridBuilder extends StatefulWidget {
const StaggeredGridBuilder({
super.key,
required this.images,
required this.onImageDoubleTapped,
});
final List<ImageBlockData> images;
final void Function(int) onImageDoubleTapped;
@override
State<StaggeredGridBuilder> createState() => _StaggeredGridBuilderState();
}
class _StaggeredGridBuilderState extends State<StaggeredGridBuilder> {
/// Split up the list of images into a list of lists of 4 images each, the
/// last list may have less than 4 images.
///
final List<List<ImageBlockData>> _splitImages = [];
@override
void initState() {
super.initState();
for (int i = 0; i < widget.images.length; i += 4) {
final end = (i + 4 < widget.images.length) ? i + 4 : widget.images.length;
_splitImages.add(widget.images.sublist(i, end));
}
}
@override
void didUpdateWidget(covariant StaggeredGridBuilder oldWidget) {
if (widget.images.length != oldWidget.images.length) {
_splitImages.clear();
for (int i = 0; i < widget.images.length; i += 4) {
final end =
(i + 4 < widget.images.length) ? i + 4 : widget.images.length;
_splitImages.add(widget.images.sublist(i, end));
}
}
super.didUpdateWidget(oldWidget);
}
@override
Widget build(BuildContext context) {
return StaggeredGrid.count(
crossAxisCount: 4,
children:
_splitImages.indexed.map(_buildTilesForImages).flattened.toList(),
);
}
List<Widget> _buildTilesForImages((int, List<ImageBlockData>) data) {
final index = data.$1;
final images = data.$2;
final isReversed = index.isOdd;
if (images.length == 4) {
return [
StaggeredGridTile.count(
crossAxisCellCount: isReversed ? 1 : 2,
mainAxisCellCount: isReversed ? 1 : 2,
child: Tile(),
),
StaggeredGridTile.count(
crossAxisCellCount: 1,
mainAxisCellCount: 1,
child: Tile(),
),
StaggeredGridTile.count(
crossAxisCellCount: isReversed ? 2 : 1,
mainAxisCellCount: isReversed ? 2 : 1,
child: Tile(),
),
StaggeredGridTile.count(
crossAxisCellCount: 2,
mainAxisCellCount: 1,
child: Tile(),
),
];
} else if (images.length == 3) {
return [
StaggeredGridTile.count(
crossAxisCellCount: 2,
mainAxisCellCount: isReversed ? 1 : 2,
child: Tile(),
),
StaggeredGridTile.count(
crossAxisCellCount: 2,
mainAxisCellCount: isReversed ? 2 : 1,
child: Tile(),
),
StaggeredGridTile.count(
crossAxisCellCount: 2,
mainAxisCellCount: 1,
child: Tile(),
),
];
} else if (images.length == 2) {
return [
StaggeredGridTile.count(
crossAxisCellCount: 2,
mainAxisCellCount: 2,
child: Tile(),
),
StaggeredGridTile.count(
crossAxisCellCount: 2,
mainAxisCellCount: 2,
child: Tile(),
),
];
} else {
return [
StaggeredGridTile.count(
crossAxisCellCount: 4,
mainAxisCellCount: 2,
child: Tile(),
),
];
}
}
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I want to use specifically the
SliverQuiltedGridDelegate
to have as boxed a layout as possible no matter the amount of items in the grid, as it's not fixed.Our use-case is when a user inserts irregular amount of end-items to a grid compared to the pattern, in such a case it would be nice to be able to change the pattern based on the length of the current segment.
Consider this pattern and code:
Which produces this result:
Now if the last image was missing, it would look like this:
Where a more fitting pattern would be something like this for the last block:
So if we could use a
patternBuilder
in some cases when needed, which provides the length of the images in the current segment, that would be very helpful.I'm willing to look into how we could go about achieving this, I know it might not be super straightforward, and might be good to completely separate the new implementation from
SliverQuiltedGridDelegate
.The text was updated successfully, but these errors were encountered: