Skip to content

Instantly share code, notes, and snippets.

@lomza
Created January 27, 2024 19:34
Show Gist options
  • Save lomza/602f2db56347dfef17ca8ca2b8239e0e to your computer and use it in GitHub Desktop.
Save lomza/602f2db56347dfef17ca8ca2b8239e0e to your computer and use it in GitHub Desktop.
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:infinite_scroll_sliver_list/get_flowers_use_case.dart';
class InfiniteScrollPage extends HookWidget {
const InfiniteScrollPage({super.key});
@override
Widget build(BuildContext context) {
final getFlowersUseCase = GetFlowersUseCase();
final scrollController = useScrollController();
final allFlowers = useState<List<String>>([]);
final isPageLoading = useState<bool>(false);
final nextPage = useState<int>(1);
final reachedEnd = useState<bool>(false);
void onScrollListener() {
if (reachedEnd.value) {
return;
}
if (!isPageLoading.value) {
isPageLoading.value = true;
Future.microtask(() async {
final newFlowers = await getFlowersUseCase.getFlowers(page: nextPage.value);
if (newFlowers.length < pageSize) {
reachedEnd.value = true;
}
allFlowers.value.addAll(newFlowers);
nextPage.value++;
isPageLoading.value = false;
});
}
}
useEffect(
() {
// Make first call and assign the result to allFlowers list
Future.microtask(() async => allFlowers.value = await getFlowersUseCase.getFlowers());
return null;
},
const [],
);
return Scaffold(
body: NotificationListener<ScrollNotification>(
onNotification: (scrollNotification) {
if (scrollNotification is ScrollEndNotification) {
onScrollListener();
}
return true;
},
child: CustomScrollView(
controller: scrollController,
slivers: [
SliverAppBar(
backgroundColor: Theme.of(context).colorScheme.inversePrimary,
title: const Text('Infinite scrolling SliverList'),
),
SliverList.separated(
separatorBuilder: (_, __) => Divider(color: Theme.of(context).colorScheme.primary),
itemBuilder: (context, index) {
// Show progress indicator on the bottom
if (allFlowers.value.length == index) {
return const Padding(
padding: EdgeInsets.only(top: 16, bottom: 16),
child: Center(child: CircularProgressIndicator()),
);
}
final flowerName = allFlowers.value[index];
return Container(
padding: const EdgeInsets.symmetric(vertical: 20, horizontal: 16),
child: Text(
flowerName,
style: TextStyle(
color: Theme.of(context).colorScheme.primary,
fontSize: 20,
fontWeight: FontWeight.w500,
),
),
);
},
itemCount: isPageLoading.value ? allFlowers.value.length + 1 : allFlowers.value.length,
),
],
),
),
);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment