import 'package:flutter/rendering.dart'; class SliverGridDelegateWithFixedHeight extends SliverGridDelegate { /// Creates a delegate that makes grid layouts with a fixed height. const SliverGridDelegateWithFixedHeight({ required this.maxCrossAxisExtent, this.mainAxisSpacing = 0.0, this.crossAxisSpacing = 0.0, this.height = 56.0, }) : assert(mainAxisSpacing >= 0), assert(crossAxisSpacing >= 0), assert(height > 0); /// The maximum extent of tiles in the cross axis. /// /// This delegate will select a cross-axis extent for the tiles that is as /// large as possible subject to the following conditions: /// /// - The extent evenly divides the cross-axis extent of the grid. /// - The extent is at most [maxCrossAxisExtent]. /// /// For example, if the grid is vertical, the grid is 500.0 pixels wide, and /// [maxCrossAxisExtent] is 150.0, this delegate will create a grid with 4 /// columns that are 125.0 pixels wide. final double maxCrossAxisExtent; /// 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; /// The height of the crossAxis. final double height; bool _debugAssertIsValid() { assert(mainAxisSpacing >= 0.0); assert(crossAxisSpacing >= 0.0); assert(height > 0.0); return true; } @override SliverGridLayout getLayout(SliverConstraints constraints) { assert(_debugAssertIsValid()); final crossAxisCount = (constraints.crossAxisExtent / (maxCrossAxisExtent + crossAxisSpacing)) .ceil(); final usableCrossAxisExtent = constraints.crossAxisExtent - crossAxisSpacing * (crossAxisCount - 1); final childCrossAxisExtent = usableCrossAxisExtent / crossAxisCount; final childMainAxisExtent = height; return SliverGridRegularTileLayout( crossAxisCount: crossAxisCount, mainAxisStride: childMainAxisExtent + mainAxisSpacing, crossAxisStride: childCrossAxisExtent + crossAxisSpacing, childMainAxisExtent: childMainAxisExtent, childCrossAxisExtent: childCrossAxisExtent, reverseCrossAxis: axisDirectionIsReversed(constraints.crossAxisDirection), ); } @override bool shouldRelayout(SliverGridDelegateWithFixedHeight oldDelegate) { return oldDelegate.maxCrossAxisExtent != maxCrossAxisExtent || oldDelegate.mainAxisSpacing != mainAxisSpacing || oldDelegate.crossAxisSpacing != crossAxisSpacing || oldDelegate.height != height; } }