Created
July 21, 2022 08:36
-
-
Save buntagonalprism/41de52dc8c4097cb2d4c6fca440110fb to your computer and use it in GitHub Desktop.
Sliver grid delegate for items with fixed height and minimum width
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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