mirror of
https://github.com/wgh136/pixes.git
synced 2025-09-27 21:07:24 +00:00
125 lines
3.5 KiB
Dart
125 lines
3.5 KiB
Dart
import 'package:flutter/rendering.dart';
|
|
import 'package:flutter/widgets.dart';
|
|
import 'package:pixes/foundation/app.dart';
|
|
|
|
class SliverGridViewWithFixedItemHeight extends StatelessWidget {
|
|
const SliverGridViewWithFixedItemHeight(
|
|
{required this.delegate,
|
|
this.maxCrossAxisExtent = double.infinity,
|
|
this.minCrossAxisExtent = 0,
|
|
required this.itemHeight,
|
|
super.key});
|
|
|
|
final SliverChildDelegate delegate;
|
|
|
|
final double maxCrossAxisExtent;
|
|
|
|
final double minCrossAxisExtent;
|
|
|
|
final double itemHeight;
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return SliverGrid(
|
|
delegate: delegate,
|
|
gridDelegate: SliverGridDelegateWithFixedHeight(
|
|
itemHeight: itemHeight,
|
|
maxCrossAxisExtent: maxCrossAxisExtent,
|
|
minCrossAxisExtent: minCrossAxisExtent),
|
|
).sliverPadding(EdgeInsets.only(bottom: context.padding.bottom));
|
|
}
|
|
}
|
|
|
|
class GridViewWithFixedItemHeight extends StatelessWidget {
|
|
const GridViewWithFixedItemHeight(
|
|
{required this.builder,
|
|
required this.itemCount,
|
|
this.maxCrossAxisExtent = double.infinity,
|
|
this.minCrossAxisExtent = 0,
|
|
required this.itemHeight,
|
|
super.key});
|
|
|
|
final Widget Function(BuildContext, int) builder;
|
|
|
|
final int itemCount;
|
|
|
|
final double maxCrossAxisExtent;
|
|
|
|
final double minCrossAxisExtent;
|
|
|
|
final double itemHeight;
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return LayoutBuilder(
|
|
builder: ((context, constraints) => GridView.builder(
|
|
gridDelegate: SliverGridDelegateWithFixedHeight(
|
|
itemHeight: itemHeight,
|
|
maxCrossAxisExtent: maxCrossAxisExtent,
|
|
minCrossAxisExtent: minCrossAxisExtent),
|
|
itemBuilder: builder,
|
|
itemCount: itemCount,
|
|
padding: EdgeInsets.only(bottom: context.padding.bottom),
|
|
)));
|
|
}
|
|
}
|
|
|
|
class SliverGridDelegateWithFixedHeight extends SliverGridDelegate {
|
|
const SliverGridDelegateWithFixedHeight({
|
|
this.maxCrossAxisExtent = double.infinity,
|
|
this.minCrossAxisExtent = 0,
|
|
required this.itemHeight,
|
|
});
|
|
|
|
final double maxCrossAxisExtent;
|
|
|
|
final double minCrossAxisExtent;
|
|
|
|
final double itemHeight;
|
|
|
|
@override
|
|
SliverGridLayout getLayout(SliverConstraints constraints) {
|
|
var crossItemsCount = calcCrossItemsCount(constraints.crossAxisExtent);
|
|
return SliverGridRegularTileLayout(
|
|
crossAxisCount: crossItemsCount,
|
|
mainAxisStride: itemHeight,
|
|
childMainAxisExtent: itemHeight,
|
|
crossAxisStride: constraints.crossAxisExtent / crossItemsCount,
|
|
childCrossAxisExtent: constraints.crossAxisExtent / crossItemsCount,
|
|
reverseCrossAxis: false);
|
|
}
|
|
|
|
int calcCrossItemsCount(double width) {
|
|
int count = 20;
|
|
var itemWidth = width / 20;
|
|
|
|
if(minCrossAxisExtent == 0) {
|
|
count = 1;
|
|
itemWidth = width;
|
|
while(itemWidth > maxCrossAxisExtent) {
|
|
count++;
|
|
itemWidth = width / count;
|
|
}
|
|
return count;
|
|
}
|
|
|
|
while (
|
|
!(itemWidth > minCrossAxisExtent && itemWidth < maxCrossAxisExtent)) {
|
|
count--;
|
|
itemWidth = width / count;
|
|
if (count == 1) {
|
|
return 1;
|
|
}
|
|
}
|
|
return count;
|
|
}
|
|
|
|
@override
|
|
bool shouldRelayout(covariant SliverGridDelegate oldDelegate) {
|
|
return oldDelegate is! SliverGridDelegateWithFixedHeight ||
|
|
oldDelegate.maxCrossAxisExtent != maxCrossAxisExtent ||
|
|
oldDelegate.minCrossAxisExtent != minCrossAxisExtent ||
|
|
oldDelegate.itemHeight != itemHeight;
|
|
}
|
|
}
|