So because I had some issues with grid view and I really didn't like aspect ration (it does not work properly in flutter web) I came up by creating "custom grid view". You can edit these widget with your needs. Each child takes the height that it needs, but you can edit it and add a default height or something.
CustomGridView:
import 'package:flutter/material.dart';
class CustomGridView extends StatelessWidget {
const CustomGridView({
super.key,
required this.crossAxisCount,
required this.length,
required this.widgetOfIndex,
this.crossAxisSpacing = 0,
this.mainAxisSpacing = 0,
this.physics,
this.shrinkWrap = false,
});
final int crossAxisCount;
final int length;
final double crossAxisSpacing;
final double mainAxisSpacing;
final Widget Function(int index) widgetOfIndex;
final ScrollPhysics? physics;
final bool shrinkWrap;
@override
Widget build(BuildContext context) {
return ListView.builder(
physics: physics,
shrinkWrap: shrinkWrap,
itemCount: (length / crossAxisCount).ceil(),
itemBuilder: (BuildContext context, int listIndex) {
return Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: List<Widget>.generate(
crossAxisCount,
(int index) {
return Expanded(
child: Padding(
padding: EdgeInsets.only(
right: index < crossAxisCount - 1 ? crossAxisSpacing / 2 : 0,
left: index > 0 ? crossAxisSpacing / 2 : 0,
bottom: mainAxisSpacing,
),
child: listIndex * crossAxisCount + index < length ? widgetOfIndex(listIndex * crossAxisCount + index) : const SizedBox(),
),
);
},
),
);
},
);
}
}
This is how you can call it:
CustomGridView(
crossAxisCount: 2,
crossAxisSpacing: 16,
length: _apartments.length,
widgetOfIndex: (int index) {
return YourWidget(_apartments[index]);
},
),
For Sliver grid view you can get this,
CustomSliverGridView:
import 'package:flutter/material.dart';
class CustomSliverGridView extends StatelessWidget {
const CustomSliverGridView({
super.key,
required this.crossAxisCount,
required this.length,
required this.widgetOfIndex,
this.crossAxisSpacing = 0,
this.mainAxisSpacing = 0,
});
final int crossAxisCount;
final int length;
final double crossAxisSpacing;
final double mainAxisSpacing;
final Widget Function(int index) widgetOfIndex;
@override
Widget build(BuildContext context) {
return SliverList(
delegate: SliverChildBuilderDelegate(
(BuildContext context, int listIndex) {
return Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: List<Widget>.generate(
crossAxisCount,
(int index) {
return Expanded(
child: Padding(
padding: EdgeInsets.only(
right: index < crossAxisCount - 1 ? crossAxisSpacing / 2 : 0,
left: index > 0 ? crossAxisSpacing / 2 : 0,
bottom: mainAxisSpacing,
),
child: listIndex * crossAxisCount + index < length ? widgetOfIndex(listIndex * crossAxisCount + index) : const SizedBox(),
),
);
},
),
);
},
childCount: (length / crossAxisCount).ceil(),
),
);
}
}
Finally you can get the custom sliver grid view like this:
CustomSliverGridView(
crossAxisCount: 2,
crossAxisSpacing: 16,
length: _apartments.length,
widgetOfIndex: (int index) {
return YourWidget(_apartments[index]);
},
)