问题描述
我正在尝试为从api中获取的 list
实施延迟加载.我为 ListView
实现了一个侦听器,以检查它何时到达底部.我在这里遇到的问题是:
I am trying to implement a lazy loading for a list
that I am fetching from api. I have implemented a listener for my ListView
to check when it reaches the bottom. The issue I have here is:
1)如何为列表设置加载项的初始数量?
1) How do I set an initial number of loaded items for my list?
2)如何在调用loadMore()方法时自动将项目添加到列表中?
2) How do I automatically add items to the list while calling my loadMore() method?
class _HomeServiceState extends State<HomePage>
with AutomaticKeepAliveClientMixin {
List<Mentor> filteredData;
List<Mentor> users = [];
@override
void initState() {
// TODO: implement initState
super.initState();
_scrollcontroller.addListener(() {
if (_scrollcontroller.position.atEdge) {
if (_scrollcontroller.position.pixels == 0){
// you are at top position
} else{
// you are at bottom position
loadMore();
}
}
});
}
@override
Widget build(BuildContext context) {
final mentors = new FutureBuilder(
future: _future,
builder: (BuildContext context, AsyncSnapshot snapshot) {
return ListView.builder(
shrinkWrap: true,
physics: ScrollPhysics(),
itemCount: filteredData.length + 1,
itemBuilder: (BuildContext context, int index) {
if (index == filteredData.length) {
return CupertinoActivityIndicator();
}
return ListTile(
leading: CircleAvatar(
maxRadius: 23,
backgroundImage: NetworkImage(NetworkUtils.host +
AuthUtils.profilePics +
filteredData[index].profile_image),
),
title: Text(
filteredData[index].first_name +
" " +
filteredData[index].last_name,
style: TextStyle(
color: Color(0xFF041F36),
fontFamily: 'Muli',
fontSize: 16.0,
)),
subtitle: Text(capitalize(filteredData[index].industry),
style: TextStyle(
color: Color(0xFF25282A),
fontFamily: 'MuliLight',
fontSize: 12.0,
)),
trailing: Text(capitalize(filteredData[index].country),
style: TextStyle(
color: Color(0xFF25282A),
fontFamily: 'MuliItalic',
fontSize: 12.0,
)),
onTap: () {
Navigator.push(
context,
SlideFromRightPageRoute(
widget: MenteeDetailPage(filteredData[index])));
},
);
},
);
}
},
);
Future<List<Mentor>> _getUsers() async {
sharedPreferences = await SharedPreferences.getInstance();
var data = await http.get(
NetworkUtils.host + AuthUtils.endPointMentors,
headers: {
'Authorization': "Bearer " + sharedPreferences.getString("token"),
'Accept': 'application/json'
},
);
var jsonData = json.decode(data.body);
for (var u in jsonData["data"]) {
Mentor user = Mentor(
u["id"]!=null ? u["id"]: "",
u["category"]!=null ? u["category"] : "",
u["email"]!=null ? u["email"]: "",
u["email_verified_at"] !=null ? u["email_verified_at"]: "",
u["first_name"] !=null ? u["first_name"]: "",
u["last_name"] != null ?u["last_name"]: "",
u["other_name"] !=null ? u["other_name"]: "",
u["country"] !=null ? u["country"]: "",
u["industry"] !=null ? u["industry"]: "",
u["gender"] !=null ? u["gender"]: "",
u["bio_interest"] !=null ? u["bio_interest"]: "",
u["phone"] !=null ?u["phone"]: "",
u["state_of_origin"] !=null ? u["state_of_origin"]: "",
u["fav_quote"] != null ? u["fav_quote"]: "",
u["profile_image"] != null ? u["profile_image"] : "",
u["terms"] !=null ? u["terms"]: "",
u["check_status"] !=null ? u["check_status"]: "",
u["current_job"] != null ? u["current_job"]: "",
u["created_at"] !=null ? u["created_at"]: "",
u["updated_at"]!=null ? u["updated_at"]: "",
u["social_id"] !=null ? u["social_id"]: "",
getFromList(u["employment"], 'company'),
getFromList(u['employment'], 'position'),
getFromList(u['education'], 'institution'),
getFromList(u['education'], 'degree'),);
users.add(user);
}
filteredData = users;
return filteredData;
}
String getFromList(Map<String, dynamic> json, String key) {
return json != null ? json[key] : "";
}
@override
void dispose() {
_scrollcontroller.dispose();
super.dispose();
}
@override
// TODO: implement wantKeepAlive
bool get wantKeepAlive => true;
loadMore() {
print("edkwj");
}
}
推荐答案
您需要检查,调用分页功能需要显示多少个项目,它可能是10,20,30,这是您的要求.在下面的示例中,我假设当时有20个项目,因此在您的API响应中,您需要检查是否正在获得20个项目,或者是否像下面这样.
You need to make check that , how many item you need to show for calling the pagination functionality , it could be 10,20,30 as your requirement. In my below example i am assuming the 20 items at time, So inside in your API response , you need to make check that you are getting the 20 items or not a time like below.
Future<List<Mentor>> _getUsers() async {
sharedPreferences = await SharedPreferences.getInstance();
var data = await http.get(
NetworkUtils.host + AuthUtils.endPointMentors,
headers: {
'Authorization': "Bearer " + sharedPreferences.getString("token"),
'Accept': 'application/json'
},
);
var jsonData = json.decode(data.body);
for (var u in jsonData["data"]) {
Mentor user = Mentor(
u["id"] != null ? u["id"] : "",
u["category"] != null ? u["category"] : "",
u["email"] != null ? u["email"] : "",
u["email_verified_at"] != null ? u["email_verified_at"] : "",
u["first_name"] != null ? u["first_name"] : "",
u["last_name"] != null ? u["last_name"] : "",
u["other_name"] != null ? u["other_name"] : "",
u["country"] != null ? u["country"] : "",
u["industry"] != null ? u["industry"] : "",
u["gender"] != null ? u["gender"] : "",
u["bio_interest"] != null ? u["bio_interest"] : "",
u["phone"] != null ? u["phone"] : "",
u["state_of_origin"] != null ? u["state_of_origin"] : "",
u["fav_quote"] != null ? u["fav_quote"] : "",
u["profile_image"] != null ? u["profile_image"] : "",
u["terms"] != null ? u["terms"] : "",
u["check_status"] != null ? u["check_status"] : "",
u["current_job"] != null ? u["current_job"] : "",
u["created_at"] != null ? u["created_at"] : "",
u["updated_at"] != null ? u["updated_at"] : "",
u["social_id"] != null ? u["social_id"] : "",
getFromList(u["employment"], 'company'),
getFromList(u['employment'], 'position'),
getFromList(u['education'], 'institution'),
getFromList(u['education'], 'degree'),);
users.add(user);
}
filteredData = users;
////HERE ARE MAKING THE CHECK THE LOAD MORE FUNCTIONALITY
if (users.length == 20) {
isLoading = true;
}
else {
isLoading = false
}
return filteredData;
}
从上面的代码中,我们知道列表中是否有 20 个项目,或者没有 isLoading
布尔值.
From above code , we come to know that there is 20 items in the list or not with isLoading
boolean.
下一步,我们需要检测listview;底部滚动表示当列表位于底部时,我们的加载更多功能应该起作用.
Next step we need to detect the listview;s bottom scroll means when list come at the bottom then our load more functionality should work.
为此 ScrollController
进行ListView底部的滚动检测.正如我创建的ScrollController列表器,并将其添加到Listview的contoller中以检测滚动.我已经创建了它的演示,请检查一次.第一次加载20个项目,然后我们将调用api加载更多项目.
For it ScrollController
for the scrolling detection at the bottom for the ListView . As i have created the ScrollController listner and added to the Listview's contoller for the detection of the scroll. I have created the demo of it , please check it once. At first time it load the 20 items and then afet we will call api to load more items.
class _HomeScreen extends State<HomeScreen> {
List dataList = new List<int>();
bool isLoading = false;
int pageCount = 1;
ScrollController _scrollController;
@override
void initState() {
super.initState();
_scrollController = new ScrollController(initialScrollOffset: 5.0)
..addListener(_scrollListener);
}
Widget build(BuildContext context) {
return MaterialApp(
title: 'Gridview',
debugShowCheckedModeBanner: false,
theme: ThemeData(
primaryColor: Colors.red,
accentColor: Color(0xFFFEF9EB),
),
home: Scaffold(
appBar: new AppBar(),
body: ListView.builder(
shrinkWrap: true,
controller: _scrollController, //// YOU ARE ADDING THE CONTROLLER HERE TO ADD THE SCROLL LISTENER
physics: ScrollPhysics(),
itemCount: filteredData.length + 1,
itemBuilder: (BuildContext context, int index) {
if (index == filteredData.length) {
return CupertinoActivityIndicator();
}
return ListTile(
);
},
)));
}
//// ADDING THE SCROLL LISTINER
_scrollListener() {
if (_scrollController.offset >=
_scrollController.position.maxScrollExtent &&
!_scrollController.position.outOfRange) {
setState(() {
print("comes to bottom $isLoading");
isLoading = true;
if (isLoading) {
print("RUNNING LOAD MORE");
pageCount = pageCount + 1;
//// CALL YOUR API HERE FOR THE NEXT FUNCTIONALITY
getUsers();
}
});
}
}
@override
void dispose() {
_scrollController.dispose();
super.dispose();
}
}
在 _scrollListener
内,您需要调用API以从分页中获取更多项目
Inside the _scrollListener
you need to call API to get more item from the pagination
这篇关于延迟加载json列表视图颤动的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!