In this example, I am trying to use the infinite_scroll_pagination package from pub.dev to build a PagedGridView. Im using colors for the grid for now but what should happen is the first 9 items are generated and when the user gets to the bottom of the page, the pagelistener will request more tiles (up until the pagesize reaches colors.length. However, the pagedgridview is _fetching automatically with the pageSize increment without any scroll behavior. I need this to work with my database when its figured out that way i dont make unnecessary reads.
What i have setup is a listview with one of its children as the PagedGridView<int, Color>. I also wrapped the body with a RefreshIndicator in attempt to manually notify the pagelistener. Either way, the gridview automatically increments the number of items by the pageSize (9) without any scroll behavior.
import 'package:flutter/material.dart';
import 'package:infinite_scroll_pagination/infinite_scroll_pagination.dart';
class InfiniteScroll extends StatefulWidget {
const InfiniteScroll({super.key});
@override
State<InfiniteScroll> createState() => _InfiniteScrollState();
}
class _InfiniteScrollState extends State<InfiniteScroll> {
final List<Color> _colors = List.generate(
100,
(index) => Color(index * 0xFFFFFF ~/ 1000).withOpacity(0.5),
);
static const int _pageSize = 9;
final PagingController<int, Color> _pagingController =
PagingController(firstPageKey: 0);
@override
void initState() {
_pagingController.addPageRequestListener(_fetchPage);
super.initState();
}
Future<void> _fetchPage(int pageKey) async {
try {
if (pageKey > _colors.length) {
_pagingController.appendLastPage([]);
return;
}
final newItesm = await Future.wait(List.generate(_pageSize,
(index) => Future.delayed(const Duration(milliseconds: 50))))
.then((_) => _colors.skip(pageKey).take(_pageSize).toList());
final isLastPage = newItesm.length < _pageSize;
if (isLastPage) {
_pagingController.appendLastPage(newItesm);
} else {
final nextPageKey = pageKey + newItesm.length;
_pagingController.appendPage(newItesm, nextPageKey);
}
} catch (e) {
_pagingController.error = e;
debugPrint(e.toString());
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: RefreshIndicator(
onRefresh: () async => _pagingController.refresh(),
child: ListView(
children: [
const Card(
child: ListTile(
title: Text("Infinite Scroll Pagination"),
subtitle: Text("Infinite Scroll Pagination"),
trailing: Icon(Icons.arrow_forward_ios),
),
),
PagedGridView<int, Color>(
pagingController: _pagingController,
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(),
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 3,
mainAxisSpacing: 4.0,
crossAxisSpacing: 4.0,
),
builderDelegate: PagedChildBuilderDelegate<Color>(
itemBuilder: (context, item, index) {
return Container(
color: item,
child: InkWell(
onTap: () {
debugPrint("Color: $item");
},
child: Center(
child: Text(
index.toString(),
style: const TextStyle(fontSize: 20),
),
),
),
);
},
),
),
],
),
),
);
}
@override
void dispose() {
_pagingController.dispose();
super.dispose();
}
}
Seems like the ListView
is not lazy loading. Removing the Card
from the Listview
and changing the Listview
to a LayoutBuilder
worked for me.
body: RefreshIndicator(
onRefresh: () async => _pagingController.refresh(),
child: LayoutBuilder(builder: (context, constraints) {
return PagedGridView<int, Color>(
pagingController: _pagingController,
shrinkWrap: true,
// physics: const NeverScrollableScrollPhysics(),
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 3,
mainAxisSpacing: 4.0,
crossAxisSpacing: 4.0,
),
builderDelegate: PagedChildBuilderDelegate<Color>(
itemBuilder: (context, item, index) {
return Container(
color: item,
child: InkWell(
onTap: () {
debugPrint("Color: $item");
},
child: Center(
child: Text(
index.toString(),
style: const TextStyle(fontSize: 20),
),
),
),
);
},
),
);
}),
),
Here's where I placed the Card
.
appBar: PreferredSize(
preferredSize: const Size.fromHeight(50), // here the desired height
child: Card(
child: ListTile(
title: Text("Infinite Scroll Pagination"),
subtitle: Text("Infinite Scroll Pagination"),
trailing: Icon(Icons.arrow_forward_ios),
),
),
),