Closed bizz84 closed 1 year ago
I figured it out. Turns out I can use a SliverPadding
with a "responsive" padding value:
class ProductsSliverAlignedGrid extends StatelessWidget {
const ProductsSliverAlignedGrid({
super.key,
required this.itemCount,
required this.itemBuilder,
});
/// Total number of items to display.
final int itemCount;
/// Function used to build a widget for a given index in the grid.
final Widget Function(BuildContext, int) itemBuilder;
@override
Widget build(BuildContext context) {
if (itemCount == 0) {
return SliverToBoxAdapter(
child: Center(
child: Text(
'No products found'.hardcoded,
style: Theme.of(context).textTheme.headline4,
),
),
);
}
// use a LayoutBuilder to determine the crossAxisCount
return SliverLayoutBuilder(builder: (context, constraints) {
final width = constraints.crossAxisExtent;
final maxWidth = min(width, Breakpoint.desktop);
// 1 column for width < 500px
// then add one more column for each 250px
final crossAxisCount = max(1, maxWidth ~/ 250);
// calculate a "responsive" padding that increases
// when the width is greater than the desktop breakpoint
final padding = width > Breakpoint.desktop + Sizes.p32
? (width - Breakpoint.desktop) / 2
: Sizes.p16;
return SliverPadding(
padding: EdgeInsets.symmetric(horizontal: padding, vertical: Sizes.p16),
sliver: SliverAlignedGrid.count(
crossAxisCount: crossAxisCount,
mainAxisSpacing: Sizes.p24,
crossAxisSpacing: Sizes.p24,
itemBuilder: itemBuilder,
itemCount: itemCount,
),
);
});
}
}
I'm trying to implement a grid layout using
SliverAlignedGrid
(great package btw!), and I've hit a wall trying to make it responsive.Here's what I'm trying to do.
When the window width is < 900, I use the full width (minus some padding) and render my items like this:
But if the width is > 900, I want to center my content like so:
I previously accomplished this using a separate package. But since that doesn't support slivers, I'm trying to use
SliverAlignedGrid
instead.So far, I have a
CustomScrollView
that contains a customProductsSliverAlignedGrid
widget inside it:This layout works but always uses the full width available.
In other parts of my code, I use a responsive widget that applies the "centered after threshold" effect to any regular widget:
But this does not work with slivers and gives this error:
So the last missing piece of the puzzle is: how do I make the content inside my sliver centered if the viewport exceed a given width? Any insights?