Gov*_*iyo 10 pagination dart flutter
我是 flutter 的新手,我一直在寻找正确的分页结果 2 天。
我按照此代码Flutter ListView 延迟加载 但没有实现我想要的。看看下面的代码。
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'dart:async';
import 'dart:convert';
main() => runApp(InitialSetupPage());
class InitialSetupPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: "API Pagination",
debugShowCheckedModeBanner: false,
theme: ThemeData(primarySwatch: Colors.green),
home: HomePage(),
);
}
}
class HomePage extends StatefulWidget {
@override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
int pageNum = 1;
bool isPageLoading = false;
List<Map<String, dynamic>> arrayOfProducts;
Future<List<Map<String, dynamic>>> _callAPIToGetListOfData() async {
isPageLoading = true;
final responseDic =
await http.post(urlStr, headers: accessToken, body: paramDic);
Map<String, dynamic> dicOfRes = json.decode(responseDic.body);
List<Map<String, dynamic>> temArr = List<Map<String, dynamic>>.from(dicOfRes["data"]["products"]);
if (pageNum == 1) {
arrayOfProducts = temArr;
} else {
arrayOfProducts.addAll(temArr);
}
return arrayOfProducts;
}
ScrollController controller;
@override
void initState() {
controller = new ScrollController()..addListener(_scrollListener);
super.initState();
}
_scrollListener() {
print(controller.position.extentAfter);
if (controller.position.extentAfter <= 0 && isPageLoading == false) {
_callAPIToGetListOfData().then((data){
setState(() {
});
});
}
}
@override
void dispose() {
controller.removeListener(_scrollListener);
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Online Products"),
centerTitle: true,
),
body: Container(
child: FutureBuilder<List<Map<String, dynamic>>>(
future: _callAPIToGetListOfData(),
builder: (BuildContext context, AsyncSnapshot snapshot) {
switch (snapshot.connectionState) {
case ConnectionState.none:
case ConnectionState.active:
case ConnectionState.waiting:
return Center(child: CircularProgressIndicator());
case ConnectionState.done:
if (snapshot.hasError) {
Text(
'YOu have some error : ${snapshot.hasError.toString()}');
} else if (snapshot.data != null) {
isPageLoading = false;
pageNum++;
print(arrayOfProducts);
return Scrollbar(
child: ListView.builder(
itemCount: arrayOfProducts.length,
controller: controller,
physics: AlwaysScrollableScrollPhysics(),
itemBuilder: (context, index) {
return ListTile(
title: Text(
'$index ${arrayOfProducts[index]['title']}'),
);
}),
);
}
}
}),
));
}
}
Run Code Online (Sandbox Code Playgroud)
因此,当我到达页面底部时,我的_scrollListener方法会被调用,并且在那里我已经设置setState(()....了重新加载小部件的方法。问题是我加载了我的实际位置,它从列表的顶部开始。那么我哪里出错了?其实我想要的。https://github.com/istyle-inc/LoadMoreTableViewController/blob/master/screen.gif
最终代码: ( @Rémi Rousselet 指导)
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'dart:async';
import 'dart:convert';
main() => runApp(InitialSetupPage());
class InitialSetupPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: "API Pagination",
debugShowCheckedModeBanner: false,
theme: ThemeData(primarySwatch: Colors.green),
home: HomePage(),
);
}
}
class HomePage extends StatefulWidget {
@override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
int pageNum = 1;
bool isPageLoading = false;
List<Map<String, dynamic>> arrayOfProducts;
ScrollController controller;
Future<List<Map<String, dynamic>>> future;
int totalRecord = 0;
@override
void initState() {
controller = new ScrollController()..addListener(_scrollListener);
future = _callAPIToGetListOfData();
super.initState();
}
@override
void dispose() {
controller.removeListener(_scrollListener);
super.dispose();
}
@override
Widget build(BuildContext context) {
final constListView = ListView.builder(
itemCount: arrayOfProducts == null ? 0 : arrayOfProducts.length,
controller: controller,
physics: AlwaysScrollableScrollPhysics(),
itemBuilder: (context, index) {
return Column(
children: <Widget>[
ListTile(
title: Text('$index ${arrayOfProducts[index]['title']}'),
leading: CircleAvatar(backgroundImage: NetworkImage(arrayOfProducts[index]['thumbnail'] ?? "")),
),
Container(
color: Colors.black12,
height: (index == arrayOfProducts.length-1 && totalRecord > arrayOfProducts.length) ? 50 : 0,
width: MediaQuery.of(context).size.width,
child:Center(
child: CircularProgressIndicator()
),
)
],
);
});
return Scaffold(
appBar: AppBar(
title: Text("Online Products"),
centerTitle: true,
),
body: Container(
child: FutureBuilder<List<Map<String, dynamic>>>(
future: future,
builder: (BuildContext context, AsyncSnapshot snapshot) {
switch (snapshot.connectionState) {
case ConnectionState.none:
case ConnectionState.active:
case ConnectionState.waiting:
return Center(child: CircularProgressIndicator());
case ConnectionState.done:
if (snapshot.hasError) {
Text(
'YOu have some error : ${snapshot.hasError.toString()}');
} else if (snapshot.data != null) {
isPageLoading = false;
print(arrayOfProducts);
return constListView;
}
}
}),
));
}
Future<List<Map<String, dynamic>>> _callAPIToGetListOfData() async {
isPageLoading = true;
final responseDic =
await http.post(urlStr, headers: accessToken, body: paramDic);
Map<String, dynamic> dicOfRes = json.decode(responseDic.body);
List<Map<String, dynamic>> temArr =
List<Map<String, dynamic>>.from(dicOfRes["data"]["products"]);
setState(() {
if (pageNum == 1) {
totalRecord = dicOfRes["total_record"];
print('============>>>>>>> $totalRecord');
arrayOfProducts = temArr;
} else {
arrayOfProducts.addAll(temArr);
}
pageNum++;
});
return arrayOfProducts;
}
_scrollListener() {
if (totalRecord == arrayOfProducts.length) {
return;
}
print(controller.position.extentAfter);
if (controller.position.extentAfter <= 0 && isPageLoading == false) {
_callAPIToGetListOfData();
}
}
}
Run Code Online (Sandbox Code Playgroud)
那行得通,但这是正确的/好方法吗?有点困惑,因为如果我到达页面末尾并向上/向下滚动,滚动时似乎有点粘..
将此添加到您的控制器侦听器
if (scrollController.position.maxScrollExtent == scrollController.offset) {
/***
* we need to get new data on page scroll end but if the last
* time when data is returned, its count should be Constants.itemsCount' (10)
*
* So we calculate every time
*
* productList.length >= (Constants.itemsCount*pageNumber)
*
* list must contain the products == Constants.itemsCount if the page number is 1
* but if page number is increased then we need to calculate the total
* number of products we have received till now example:
* first time on page scroll if last count of productList is Constants.itemsCount
* then increase the page number and get new data.
* Now page number is 2, now we have to check the count of the productList
* if it is==Constants.itemsCount*pageNumber (20 in current case) then we have
* to get data again, if not then we assume, server has not more data then
* we currently have.
*
*/
if (productList.length >= (Constants.itemsCount * pageNumber) &&
!isLoading) {
pageNumber++;
print("PAGE NUMBER $pageNumber");
print("getting data");
getProducts(false); // Hit API to get new data
}
}
Run Code Online (Sandbox Code Playgroud)
https://pub.dartlang.org/packages/loadmore
您可以使用这个包,或者您可以查看代码并重做以满足您的需要
| 归档时间: |
|
| 查看次数: |
30277 次 |
| 最近记录: |