Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save buntagonalprism/41de52dc8c4097cb2d4c6fca440110fb to your computer and use it in GitHub Desktop.
Save buntagonalprism/41de52dc8c4097cb2d4c6fca440110fb to your computer and use it in GitHub Desktop.
Sliver grid delegate for items with fixed height and minimum width
import 'dart:math' as math;
import 'package:flutter/rendering.dart';
class SliverGridDelegateWithFixedMainAxisExtent extends SliverGridDelegate {
/// Creates a delegate that makes grid layouts with tiles that have a fixed
/// main axis extent and a minimum cross axis extent. This delegate will
/// attempt to fit as many items as possible in the cross axis while respecting
/// the minimum width.
///
/// All of the arguments must not be null.
const SliverGridDelegateWithFixedMainAxisExtent({
required this.mainAxisExtent,
required this.minCrossAxisExtent,
this.mainAxisSpacing = 0.0,
this.crossAxisSpacing = 0.0,
}) : assert(mainAxisExtent > 0),
assert(minCrossAxisExtent > 0),
assert(mainAxisSpacing >= 0),
assert(crossAxisSpacing >= 0);
/// The extend of tiles in the main axis
final double mainAxisExtent;
/// The minimum extent of tiles in the cross axis.
///
/// This delegate will select a cross-axis extent for the tiles that is as
/// small as possible subject to the following conditions:
///
/// - The extent evenly divides the cross-axis extent of the grid.
/// - The extent is at least [minCrossAxisExtent].
///
/// For example, if the grid is vertical, the grid is 600.0 pixels wide, and
/// [minCrossAxisExtent] is 180.0, this delegate will create a grid with 3
/// columns that are 200.0 pixels wide.
final double minCrossAxisExtent;
/// The number of logical pixels between each child along the main axis.
final double mainAxisSpacing;
/// The number of logical pixels between each child along the cross axis.
final double crossAxisSpacing;
@override
SliverGridLayout getLayout(SliverConstraints constraints) {
final int crossAxisCount =
(constraints.crossAxisExtent / (minCrossAxisExtent + crossAxisSpacing)).floor();
final double usableCrossAxisExtent = math.max(
0.0,
constraints.crossAxisExtent - crossAxisSpacing * (crossAxisCount - 1),
);
final double childCrossAxisExtent = usableCrossAxisExtent / crossAxisCount;
final double childMainAxisExtent = mainAxisExtent;
return SliverGridRegularTileLayout(
crossAxisCount: crossAxisCount,
mainAxisStride: childMainAxisExtent + mainAxisSpacing,
crossAxisStride: childCrossAxisExtent + crossAxisSpacing,
childMainAxisExtent: childMainAxisExtent,
childCrossAxisExtent: childCrossAxisExtent,
reverseCrossAxis: axisDirectionIsReversed(constraints.crossAxisDirection),
);
}
@override
bool shouldRelayout(SliverGridDelegateWithFixedMainAxisExtent oldDelegate) {
return oldDelegate.mainAxisExtent != mainAxisExtent ||
oldDelegate.minCrossAxisExtent != minCrossAxisExtent ||
oldDelegate.mainAxisSpacing != mainAxisSpacing ||
oldDelegate.crossAxisSpacing != crossAxisSpacing;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment