[英]How to perform Pagination in Flutter
我一直在閱讀有關顫振分頁的各種文章,但似乎沒有一篇適合我。 我正在使用的 API 端點看起來像這樣http://camx.heropp.com/api/connect?offset=0 (這是一個示例鏈接,因此它不起作用)請求看起來像這樣
{
"result": {
"connectUsers": [
{
"_id": "5f6a412d2ea9350017bec99f",
"userProfile": {
"rep_points": 0.75,
"visits": 0,
"bio": "Nothing for you ",
"gender": "Male",
"university": "University Of Technology",
"avatar": "https://camx.heroapp.com/5f6a412d2ea9350017bec99f"
},
"name": "Joseph Henshaw ",
"userTag": "bigjo",
"id": "5f6a412d2ea9350017bec99f",
"sameCampus": true
},
{
"_id": "5f6bbf1cbd5faa00170d92b1",
"userProfile": {
"rep_points": 0,
"visits": 0
},
"name": "John Doe",
"userTag": "@doee",
"id": "5f6bbf1cbd5faa00170d92b1",
"sameCampus": false
}
]
}
}
我想要實現的是對來自 api 的數據進行分頁..偏移量從 0 開始並隨着 10 增加,即獲得更多數據 0ffset=20..30.. 等等
這是我為了獲得上面顯示的 JSON 響應而發出的請求
Future<void> fetchConnect() async {
var uri = Uri.parse('http://campusx.herokuapp.com/api/v1/users/connect');
uri = uri.replace(query: 'offset=$offsetNumber');
print(uri);
try {
final response = await http.get(
uri,
headers: {
HttpHeaders.authorizationHeader: "Bearer $userToken",
},
);
// List<Photo> fetchedPhotos = Photo.parseList(json.decode(response.body));
if (response.statusCode == 200 || response.statusCode == 201) {
print("IT works")
} else {
print(response.statusCode);
}
List<ConnectUsers> fetchedConnects =
ConnectUsers.parseList(json.decode(response.body));
setState(() {
connectMore = fetchedConnects.length == defaultConnectsPerPageCount;
loading = false;
offsetNumber = offsetNumber + 10;
connects.addAll(fetchedConnects);
});
} catch (e) {
setState(() {
loading = false;
error = true;
});
}
}
這就是我用於顯示數據的 UI 獲取方式(小部件 getConnect 放置在我的 Scaffold 主體中
Widget getConnects() {
if (connects.isEmpty) {
if (loading) {
return Center(
child: Padding(
padding: const EdgeInsets.all(8),
child: CircularProgressIndicator(),
));
} else if (error) {
return Center(
child: InkWell(
onTap: () {
setState(() {
loading = true;
error = false;
fetchConnects();
});
},
child: Padding(
padding: const EdgeInsets.all(16),
child: Text("Error while loading connects, tap to try again"),
),
));
}
} else {
return ListView.builder(
itemCount: connects.length + (connectMore ? 10 : 0),
itemBuilder: (context, index) {
if (index == connects.length - nextPageThreshold) {
fetchConnects();
}
if (index == connects.length) {
if (error) {
return Center(
child: InkWell(
onTap: () {
setState(() {
loading = true;
error = false;
fetchConnects();
});
},
child: Padding(
padding: const EdgeInsets.all(16),
child:
Text("Error while loading connects, tap to try agin"),
),
));
} else {
return Center(
child: Padding(
padding: const EdgeInsets.all(8),
child: CircularProgressIndicator(),
));
}
}
// final Photo photo = photos[index];
final ConnectUsers connect = connects[index];
return Card(
child: Column(
children: <Widget>[
// Image.network(
// connect.name.connectUsers[index].userProfile.avatar,
// fit: BoxFit.fitWidth,
// width: double.infinity,
// height: 160,
// ),
Padding(
padding: const EdgeInsets.all(16),
child: Text(connect.name,
// connect
// .result.connectUsers[index].userProfile.university,
style: TextStyle(
fontWeight: FontWeight.bold, fontSize: 16)),
),
],
),
);
});
}
return Container();
}
這是我在使用此代碼時遇到的錯誤
The getter 'isEmpty' was called on null.
Receiver: null
Tried calling: isEmpty
看起來您正在小部件中調用connects.isEmpty,但您沒有初始化connects -> connected 為空,因此您會收到上述錯誤。 您可以進行空檢查或初始化連接
...
// initialise so connects is not null
connects = []
...
Widget getConnects() {
if (connects.isEmpty) {
if (loading) {
return Center(
(...)
Widget getConnects() {
// do a null check before calling member
if (connects == null || connects.isEmpty) {
if (loading) {
return Center(
(...)
import 'package:flutter/foundation.dart';
ConnectModel payloadFromJson(String str) =>
ConnectModel.fromJson(json.decode(str));
String payloadToJson(ConnectModel data) => json.encode(data.toJson());
class ConnectModel {
ConnectModel({
this.result,
});
Result result;
factory ConnectModel.fromJson(Map<String, dynamic> json) => ConnectModel(
result: Result.fromJson(json["result"]),
);
Map<String, dynamic> toJson() => {
"result": result.toJson(),
};
}
class Result {
Result({
this.connect,
});
List<Connect> connect;
factory Result.fromJson(Map<String, dynamic> json) => Result(
connect: List<Connect>.from(
json["connectUsers"].map((x) => Connect.fromJson(x))),
);
Map<String, dynamic> toJson() => {
"connectUsers": List<dynamic>.from(connect.map((x) => x.toJson())),
};
}
class Connect with ChangeNotifier {
Connect({
this.id,
this.name,
this.userTag,
this.university,
this.checkIsFollowing,
this.avatar,
});
String name;
String userTag;
String id;
String university;
String avatar;
bool checkIsFollowing;
factory Connect.fromJson(Map<String, dynamic> json) => Connect(
id: json["_id"],
name: json["name"],
userTag: json["userTag"],
university: json["userProfile"]["university"],
checkIsFollowing: json["checkIsFollowing"],
avatar: json["userProfile"]["avatar"],
);
Map<String, dynamic> toJson() => {
"_id": id,
"name": name,
"userTag": userTag,
"userProfile"
"university": university,
"userProfile"
"avatar": avatar,
"checkIsFollowing": checkIsFollowing
};
}
這是我的方法,其中 offsetNumber 默認初始化為 0
List<Connect> mainList = [];
List<String> nameList = [];
Future<List<Connect>> getConnectionsList(var offsetNumber) async {
var uri = "http://campusx.herokuapp.com/api/v1/users/connect?$offsetNumber";
var token = "pass_your_token_here";
try {
final response =
await http.get(uri, headers: {"Authorization": "Bearer $token"});
if (response.statusCode == 200) {
var data = json.decode(response.body);
var d = data['result']['connectUsers'];
for (var u in d) {
Connect c = Connect.fromJson(u);
mainList.add(c);
}
setState(() {
nameList = mainList.map((e) => e.name).toList();
//add other parameters gotten from the endpoint here, i used name only for test purposes
});
} else {
print(response.body);
}
} catch (e) {
print(e);
}
return mainList;
}
這是我在其中顯示名稱的 ListView 構建器
ListView.builder(
itemCount: mainList.length,
itemBuilder: (_, index) {
return Container(
height: 120,
child: Text(
nameList[index],
style: TextStyle(fontSize: 39),
),
);
},
)
然后 onClick 或按鈕,或者當列表到達手機屏幕底部時,您將 setState (() {}); 並增加 offsetNumber 的大小。 像這樣的東西:
setState(() {
offsetNumber = offsetNumber + 10;
future = getConnectionsList(offsetNumber);
});
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.