I'm working on a Flutter app where I need to display items in a horizontally scrolling gridview. I want the [tag:GridView ]to behave like a paginated view, where each "page" scrolls exactly by one set of items (like a pageview), but I’m running into issues with items getting cropped.
PageviewPhysic scroll to item crop issue image
I set up my gridviewwith pagescrollphysics to achieve a paginated scroll effect, and my grid is set to display items in a 3x3 format. However, when I scroll, the next "page" starts midway through an item, resulting in the items getting partially cropped on the left side.
Here's my current code:
GridView.builder(
// controller: controller,
physics: PageScrollPhysics(),
scrollDirection: Axis.horizontal,
itemCount: 9,
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
childAspectRatio: 2 / 8.80,
mainAxisSpacing: 10,
crossAxisSpacing: 0,
crossAxisCount: 3,
),
itemBuilder: (context, index) {
return Row(
children: [
ClipRRect(
borderRadius: BorderRadius.circular(8),
child: Image(
image: AssetImage('assets/images/appicon.png'),
height: 50,
width: 50,
),
),
SizedBox(width: 5),
Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
"App Name",
style: TextStyle(
fontSize: 16,
height: 1,
),
),
Text(
"App Type",
style: TextStyle(
fontWeight: FontWeight.w400,
),
),
],
)
],
);
},
),
I want each "page" scroll in the GridView to display exactly 3 columns per page and snap neatly to the beginning of the next set of grid items, without any items being cropped or partially displayed.
What you seek I think is a PageView
. PageView
animates between pages in similar fashion with the example in the link you provided.
Wrap your GridView
with a PageView
like in this example.
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Horizontal GridView Pagination',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: Scaffold(
appBar: AppBar(
title: Text('Horizontal GridView Pagination'),
),
body: PaginatedHorizontalGrid(),
),
);
}
}
class PaginatedHorizontalGrid extends StatelessWidget {
// Sample list of items for the grid
final List<String> items = List.generate(20, (index) => 'Item ${index + 1}');
@override
Widget build(BuildContext context) {
// Calculate the number of pages needed, with 3 items per page
int pageCount = (items.length / 3).ceil();
return PageView.builder(
scrollDirection: Axis.horizontal,
itemCount: pageCount,
itemBuilder: (context, pageIndex) {
// Calculate the starting index for each page
int startIndex = pageIndex * 3;
// Get the subset of items for the current page
List<String> pageItems = items.skip(startIndex).take(3).toList();
return GridView.builder(
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 1, // 1 row
mainAxisSpacing: 10,
crossAxisSpacing: 10,
childAspectRatio: 1.5, // Adjust as needed for item size
),
itemCount: pageItems.length,
padding: EdgeInsets.all(20),
itemBuilder: (context, index) {
return Container(
color: Colors.blueAccent,
alignment: Alignment.center,
child: Text(
pageItems[index],
style: TextStyle(color: Colors.white, fontSize: 18),
),
);
},
);
},
);
}
}