Skip to content

Instantly share code, notes, and snippets.

@GAM3RG33K
Created November 18, 2021 09:50
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save GAM3RG33K/e7b89bdb8d8d0efff1371680f0ed59eb to your computer and use it in GitHub Desktop.
Save GAM3RG33K/e7b89bdb8d8d0efff1371680f0ed59eb to your computer and use it in GitHub Desktop.
Pagination View implementation for Big data source
import 'package:flutter/material.dart';
class PaginationView extends StatefulWidget {
final int maxCountPerPage;
final int totalCount;
final Widget Function(BuildContext context, int start, int end) builder;
final VoidCallback? onNext;
final VoidCallback? onPrevious;
const PaginationView({
Key? key,
required this.maxCountPerPage,
required this.totalCount,
required this.builder,
this.onNext,
this.onPrevious,
}) : super(key: key);
@override
State<PaginationView> createState() => _PaginationViewState();
}
class _PaginationViewState extends State<PaginationView> {
final ValueNotifier<int> _indexNotifier = ValueNotifier(0);
int get maxPages => (widget.totalCount ~/ widget.maxCountPerPage);
@override
Widget build(BuildContext context) {
return ValueListenableBuilder<int>(
valueListenable: _indexNotifier,
builder: (BuildContext context, int pageIndex, Widget? child) {
final maxPerPage = widget.maxCountPerPage;
final total = widget.totalCount;
var startIndex = (pageIndex) * maxPerPage;
var endIndex = startIndex + maxPerPage;
startIndex = getProperIndex(startIndex, 0, total - 1);
endIndex = getProperIndex(endIndex, 0, total);
return Column(
children: [
SizedBox(
height: 76,
child: Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
_buildButton(
icon: Icons.chevron_left,
onTap: () {
final shouldAllow = _goToPreviousPage();
if (shouldAllow) {
widget.onPrevious?.call();
}
},
),
_buildText('${startIndex + 1} - ${endIndex + 1}'),
_buildButton(
icon: Icons.chevron_right,
onTap: () {
final shouldAllow = _goToNextPage();
if (shouldAllow) {
widget.onNext?.call();
}
},
),
],
),
),
Expanded(
child: widget.builder(context, startIndex, endIndex),
),
],
);
},
);
}
Widget _buildText(String data) {
return Padding(
padding: const EdgeInsets.symmetric(
horizontal: 20,
),
child: Text(
data,
style: const TextStyle(
fontSize: 20,
color: Colors.black,
fontWeight: FontWeight.w700,
),
),
);
}
bool _goToPreviousPage() {
final currentPage = _indexNotifier.value;
if (currentPage <= 0) {
debugPrint('No previous items');
return false;
}
_indexNotifier.value = currentPage - 1;
return true;
}
bool _goToNextPage() {
final currentPage = _indexNotifier.value;
if (currentPage >= maxPages) {
debugPrint('No next items');
return false;
}
_indexNotifier.value = currentPage + 1;
return true;
}
int getProperIndex(int index, int min, int max) {
if (index < min) return min;
if (index >= max) return max;
return index;
}
Widget _buildButton({
required IconData icon,
required onTap,
}) {
return GestureDetector(
child: Padding(
padding: const EdgeInsets.symmetric(
vertical: 10,
horizontal: 10,
),
child: Center(
child: Icon(
icon,
color: Colors.black,
size: 40,
),
),
),
onTap: onTap,
);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment