Flutter pagination
Packages :
flutter pub add http
Source code :
main.dart
xxxxxxxxxx
import 'package:demo_app/fetch_data.dart';
import 'package:demo_app/item_model.dart';
import 'package:flutter/material.dart';
​
void main() {
runApp(const MaterialApp(
debugShowCheckedModeBanner: false,
home: PaginationApp(),
));
}
​
class PaginationApp extends StatefulWidget {
const PaginationApp({Key? key}) : super(key: key);
​
@override
State<PaginationApp> createState() => _PaginationAppState();
}
​
class _PaginationAppState extends State<PaginationApp> {
List<Item> datas = [];
ScrollController scrollController = ScrollController();
final FetchData _fetchData = FetchData();
bool isLoading = false;
@override
void initState() {
// TODO: implement initState
super.initState();
fetchDataByPage();
scrollController.addListener(() => scrollListener());
}
​
scrollListener() {
if (scrollController.position.pixels >=
scrollController.position.maxScrollExtent &&
datas.isNotEmpty) {
fetchDataByPage(isLoadMore: true);
print("reached bottom");
}
}
​
fetchDataByPage({bool isLoadMore = false}) async {
_fetchData.isLoadMore = isLoadMore;
setState(() {
isLoading = true;
});
await _fetchData.prepareData().then((getDatas) {
setState(() {
datas = getDatas;
isLoading = false;
});
});
}
​
@override
Widget build(BuildContext context) {
String perpage = _fetchData.perpage.toString();
return Scaffold(
appBar: AppBar(
centerTitle: true,
title: Text(
"List View With Pagination($perpage)",
style: const TextStyle(
color: Color.fromARGB(255, 243, 243, 243),
fontWeight: FontWeight.bold),
),
),
body: buildPageBody(),
);
}
​
Widget buildPageBody() {
return isLoading && datas.isEmpty
? const Center(
child: CircularProgressIndicator(
color: Colors.lightBlue,
),
)
: SingleChildScrollView(
child: RefreshIndicator(
child: Column(
children: [
buildListView(),
if (isLoading)
const Center(
child: CircularProgressIndicator(
color: Colors.lightBlue,
),
)
],
),
onRefresh: () {
setState(() {
datas = [];
});
return fetchDataByPage();
}),
);
}
​
Widget buildListView() {
return datas.isNotEmpty
? SizedBox(
height: MediaQuery.of(context).size.height,
child: ListView(
controller: scrollController,
children: buildItem(),
),
)
: const Center(
child: Padding(
padding: EdgeInsets.all(8.0),
child: Text("Data not found"),
));
}
​
List<Widget> buildItem() {
return datas.map((Item item) {
return Card(
child: Padding(
padding: const EdgeInsets.all(15),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text("Score : ${item.score}"),
Text("Title : ${item.title}"),
],
),
),
);
}).toList();
}
}
​
item_model.dart
xxxxxxxxxx
class Item {
String score = "";
String title = "";
​
prepareitem(Map item) {
score = item['_score'].toString();
title = item['title'];
}
}
​
fetch_data.dart
xxxxxxxxxx
import 'dart:convert' as convert;
import 'package:demo_app/item_model.dart';
import 'package:http/http.dart' as http;
​
class FetchData {
int perpage = 10;
int page = 1;
bool isLoadMore = false;
Future<Map> getDataFromApi() async {
if (isLoadMore) {
page++;
perpage = perpage * page;
} else {
page = 1;
perpage = 10;
isLoadMore = false;
}
//https://api.artic.edu/api/v1/artworks/search?limit=10&page=1
var url = Uri.https('api.artic.edu', '/api/v1/artworks/search',
{'limit': perpage.toString()});
​
Map jsonResponse = {};
// Await the http get response, then decode the json-formatted response.
var response = await http.get(url);
if (response.statusCode == 200) {
jsonResponse = convert.jsonDecode(response.body) as Map<String, dynamic>;
} else {
print('Request failed with status: ${response.statusCode}.');
}
​
return jsonResponse;
}
​
Future<List<Item>> prepareData() async {
List<Item> list = [];
final getData = await getDataFromApi();
List caseData = getData['data'] as List;
// print(getData['data']);
caseData.map((eachitem) {
// print(eachitem);
Item item = Item();
item.prepareitem(eachitem);
list.add(item);
}).toList();
return list;
}
}
​