pagination_grid_view 1.0.1 copy "pagination_grid_view: ^1.0.1" to clipboard
pagination_grid_view: ^1.0.1 copied to clipboard

A Flutter grid view with built-in pagination, pull-to-refresh, empty states, and loading indicators. Perfect for image galleries, product grids, and any paginated grid layout.

pagination_grid_view #

A Flutter grid view widget with built-in pagination support. Automatically loads more items when scrolling near the bottom.

pub package

Features #

📱 Auto Pagination - Loads more data automatically when scrolling
🔄 Pull to Refresh - Built-in refresh support
🎨 Customizable - Loading indicators, empty states, error widgets
📐 Responsive - Fixed columns or max extent mode
Zero Dependencies - Pure Flutter
🎯 Type Safe - Generic support for any data type
🚀 Easy to Use - Simple, intuitive API


Installation #

dependencies:
  pagination_grid_view: ^1.0.1

Quick Start #

import 'package:pagination_grid_view/pagination_grid_view.dart';

PaginationGridView<Product>(
  items: products,
  onLoadMore: () async {
    final newProducts = await fetchMoreProducts();
    setState(() => products.addAll(newProducts));
  },
  itemBuilder: (context, product, index) => ProductCard(product),
  crossAxisCount: 2,
  hasMoreData: hasMoreProducts,
)

Usage Examples #

1. Basic Grid with 2 Columns #

PaginationGridView<String>(
  items: items,
  onLoadMore: () async {
    await Future.delayed(Duration(seconds: 1));
    setState(() {
      items.addAll(List.generate(10, (i) => 'Item ${items.length + i}'));
    });
  },
  itemBuilder: (context, item, index) => Card(
    child: Center(child: Text(item)),
  ),
  crossAxisCount: 2,
  hasMoreData: items.length < 100,
)
PaginationGridView<ImageData>(
  items: images,
  onLoadMore: loadMoreImages,
  itemBuilder: (context, image, index) => InkWell(
    onTap: () => viewImage(image),
    child: Image.network(
      image.url,
      fit: BoxFit.cover,
    ),
  ),
  crossAxisCount: 3,
  childAspectRatio: 1.0,
  crossAxisSpacing: 4,
  mainAxisSpacing: 4,
  hasMoreData: hasMoreImages,
  padding: EdgeInsets.all(4),
)

3. Product Grid with Pull-to-Refresh #

PaginationGridView<Product>(
  items: products,
  onLoadMore: () async {
    final newProducts = await api.fetchProducts(page: currentPage);
    setState(() {
      products.addAll(newProducts);
      currentPage++;
    });
  },
  onRefresh: () async {
    final freshProducts = await api.fetchProducts(page: 1);
    setState(() {
      products = freshProducts;
      currentPage = 2;
    });
  },
  itemBuilder: (context, product, index) => ProductCard(
    product: product,
    onTap: () => Navigator.push(...),
  ),
  crossAxisCount: 2,
  hasMoreData: currentPage <= totalPages,
  enablePullToRefresh: true,
)

4. Responsive Grid (Max Extent) #

Automatically adjusts column count based on screen width:

PaginationGridView.extent(
  items: products,
  onLoadMore: loadMore,
  itemBuilder: (context, product, index) => ProductCard(product),
  maxCrossAxisExtent: 200, // Max width per item
  hasMoreData: hasMore,
)

5. Custom Loading & Empty States #

PaginationGridView<Item>(
  items: items,
  onLoadMore: loadMore,
  itemBuilder: (context, item, index) => ItemCard(item),
  crossAxisCount: 2,
  hasMoreData: hasMore,
  isLoading: isLoadingInitial,

  // Custom loading indicator
  loadingWidget: Column(
    mainAxisAlignment: MainAxisAlignment.center,
    children: [
      CircularProgressIndicator(color: Colors.purple),
      SizedBox(height: 16),
      Text('Loading awesome content...'),
    ],
  ),

  // Custom empty state
  emptyWidget: Column(
    mainAxisAlignment: MainAxisAlignment.center,
    children: [
      Icon(Icons.search_off, size: 64, color: Colors.grey),
      SizedBox(height: 16),
      Text('No items found'),
      SizedBox(height: 8),
      ElevatedButton(
        onPressed: () => reload(),
        child: Text('Reload'),
      ),
    ],
  ),
)

6. With Error Handling #

PaginationGridView<Product>(
  items: products,
  onLoadMore: () async {
    try {
      final newProducts = await api.fetchProducts();
      setState(() {
        products.addAll(newProducts);
        hasError = false;
      });
    } catch (e) {
      setState(() => hasError = true);
    }
  },
  itemBuilder: (context, product, index) => ProductCard(product),
  crossAxisCount: 2,
  hasMoreData: hasMore,
  hasError: hasError,
  errorWidget: Column(
    mainAxisAlignment: MainAxisAlignment.center,
    children: [
      Icon(Icons.error_outline, size: 64, color: Colors.red),
      SizedBox(height: 16),
      Text('Failed to load products'),
      TextButton(
        onPressed: () => retry(),
        child: Text('Retry'),
      ),
    ],
  ),
)

7. Pinterest-Style (Different Aspect Ratios) #

// Use staggered grid package for variable heights
// Or use fixed aspect ratios:
PaginationGridView<Pin>(
  items: pins,
  onLoadMore: loadMore,
  itemBuilder: (context, pin, index) => PinCard(pin),
  crossAxisCount: 2,
  childAspectRatio: 0.7, // Taller items
  hasMoreData: hasMore,
)

API Reference #

PaginationGridView Parameters #

Parameter Type Default Description
items List<T> required List of items to display
itemBuilder Widget Function(...) required Builder for each item
onLoadMore Future<void> Function() required Called to load more data
hasMoreData bool required Whether there's more data
crossAxisCount int 2 Number of columns
childAspectRatio double 1.0 Width/height ratio
crossAxisSpacing double 10.0 Horizontal spacing
mainAxisSpacing double 10.0 Vertical spacing
enablePullToRefresh bool true Enable refresh gesture
onRefresh Future<void> Function()? null Refresh callback
isLoading bool false Initial loading state
loadingWidget Widget? null Custom loading indicator
emptyWidget Widget? null Custom empty state
errorWidget Widget? null Custom error widget
hasError bool false Error state
padding EdgeInsetsGeometry? 16 all Grid padding
loadMoreThreshold double 0.8 Trigger distance (0-1)
showLoadingAtBottom bool true Show bottom loader
scrollController ScrollController? null Custom controller
physics ScrollPhysics? null Scroll physics
shrinkWrap bool false Shrink wrap
primary bool? null Primary scroll view
reverse bool false Reverse grid

PaginationGridView.extent Parameters #

All above parameters, plus:

Parameter Type Default Description
maxCrossAxisExtent double 200 Max item width

Common Patterns #

State Management with BLoC #

BlocBuilder<ProductBloc, ProductState>(
  builder: (context, state) {
    return PaginationGridView<Product>(
      items: state.products,
      onLoadMore: () => context.read<ProductBloc>().add(LoadMore()),
      onRefresh: () => context.read<ProductBloc>().add(Refresh()),
      itemBuilder: (context, product, index) => ProductCard(product),
      crossAxisCount: 2,
      hasMoreData: state.hasMore,
      isLoading: state.isLoading,
      hasError: state.hasError,
    );
  },
)

With Provider #

Consumer<ProductProvider>(
  builder: (context, provider, child) {
    return PaginationGridView<Product>(
      items: provider.products,
      onLoadMore: provider.loadMore,
      onRefresh: provider.refresh,
      itemBuilder: (context, product, index) => ProductCard(product),
      crossAxisCount: 2,
      hasMoreData: provider.hasMore,
      isLoading: provider.isLoading,
    );
  },
)

Tips & Best Practices #

  1. Avoid Rebuilding: Use const constructors where possible
  2. Handle Errors: Always implement error handling in onLoadMore
  3. Debounce Loads: Prevent multiple simultaneous load requests
  4. Cache Data: Cache loaded items to improve performance
  5. Responsive: Use .extent() for responsive layouts
  6. Images: Use cached_network_image for better performance

Use Cases #

✅ Product grids (e-commerce)
✅ Image galleries
✅ Video thumbnails
✅ User avatars
✅ Social media feeds (grid view)
✅ File browsers
✅ Icon pickers
✅ Category selectors


License #

MIT License - see LICENSE file.

Support #

Star on GitHub
🐛 Report Issues

1
likes
150
points
14
downloads

Documentation

API reference

Publisher

verified publisherdhananjayafernando.online

Weekly Downloads

A Flutter grid view with built-in pagination, pull-to-refresh, empty states, and loading indicators. Perfect for image galleries, product grids, and any paginated grid layout.

Topics

#grid #pagination #infinite-scroll #listview #widget

License

MIT (license)

Dependencies

flutter

More

Packages that depend on pagination_grid_view