flutter - 如何通过在 Flutter 中调用 Future 来加载更多项目并在 Listview 构建器中显示
问题描述
滚动并到达列表末尾时如何加载更多项目。我通过将 gcm 值传递给我的 url 来获取新的页面数据,但它不会附加已经存在的列表,而是清除现有数据并显示新列表。
以下是我的代码,如果有人可以请帮助我。
class Herbs extends StatefulWidget {
final String title;
Herbs(this.title);
@override
_HerbsState createState() => new _HerbsState();
}
class _HerbsState extends State<Herbs> {
ScrollController _scrollController = new ScrollController();
var cname;
String gcm;
@override
void initState() {
if (gcm == null) {
gcm = '';
this.fetchPost(gcm);
} else {
this.fetchPost(gcm);
}
_scrollController.addListener(_scrollListener);
super.initState();
}
_scrollListener() {
if (_scrollController.offset >=
_scrollController.position.maxScrollExtent &&
!_scrollController.position.outOfRange) {
setState(() {
print("reach the bottom");
fetchPost(gcm);
});
}
}
@override
void dispose() {
_scrollController.dispose();
super.dispose();
}
Future<Herbslist> fetchPost(gcm) async {
String url =
'https://example.org/api.php?action=query&gcmtitle=Category:$cname&pilimit=max&prop=pageimages&pithumbsize=200&generator=categorymembers&format=json&gcmcontinue=$gcm';
final response = await http.get(url);
print(url);
if (response.statusCode == 200) {
var data = Herbslist.fromJson(json.decode(response.body));
return data;
} else {
throw (e) {
print("Exception thrown: $e");
Exception(e);
};
}
}
@override
Widget build(BuildContext context) {
cname = widget.title;
return new Scaffold(
appBar: AppBar(
title: Align(
alignment: Alignment(-0.2, 0.3),
child: Text(
cname,
),
),
),
body: Center(
child: FutureBuilder<Herbslist>(
future: fetchPost(gcm),
builder: (context, snapshot) {
if (snapshot.hasData) {
List pages = snapshot.data.query.pages.values.toList();
return Scrollbar(
child: ListView.builder(
controller: _scrollController,
shrinkWrap: true,
itemCount: pages.length,
itemBuilder: (BuildContext context, int index) {
gcm = snapshot.data.herbslistContinue.gcmcontinue;
var img = pages[index].thumbnail.source;
return Container(
child: Card(
child: GestureDetector(
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => Detailpage(
pages[index].title,
),
));
},
child: ListTile(
contentPadding: EdgeInsets.symmetric(
horizontal: 8.0, vertical: 8.0),
leading: Container(
padding: EdgeInsets.only(right: 10.0),
decoration: new BoxDecoration(
border: new Border(
right: new BorderSide(
width: 1.5, color: Colors.grey)),
),
// ignore: unrelated_type_equality_checks
child: img == img.isEmpty
? SizedBox(
height: 50.0,
width: 50.0,
child: Image.asset('images.png'),
)
: SizedBox(
height: 50.0,
width: 50.0,
child: FadeInImage.assetNetwork(
placeholder: 'images.png',
image: img,
fit: BoxFit.fill,
),
)),
title: Text(pages[index].title),
),
)));
},
),
);
} else {
return Center(
child: CircularProgressIndicator(),
);
}
},
),
),
);
}
}
JSON
{
"batchcomplete": "",
"continue": {
"gcmcontinue": "page|41434143494120464552525547494e4541202d204152494d45444148|3704",
"continue": "gcmcontinue||"
},
"query": {
"pages": {
"225": {
"pageid": 225,
"ns": 0,
"title": "Abrus precatorius - Gunja",
"thumbnail": {
"source": "https://example.org/images/thumb/c/cb/Abrus_precatorius_%281463017430%29.jpg/600px-Abrus_precatorius_%281463017430%29.jpg",
"width": 600,
"height": 450
},
"pageimage": "Abrus_precatorius_(1463017430).jpg"
},
"625": {
"pageid": 625,
"ns": 0,
"title": "Abies webbiana - Talispatra",
"thumbnail": {
"source": "https://example.org/images/thumb/b/b1/Red_fir.jpg/397px-Red_fir.jpg",
"width": 397,
"height": 600
},
"pageimage": "Red_fir.jpg"
},
"15995": {
"pageid": 15995,
"ns": 0,
"title": "Abelmoschus esculentus - Bhenda",
"thumbnail": {
"source": "https://upload.wikimedia.org/wikipedia/commons/thumb/d/d0/India_-_Koyambedu_Market_-_Ladies_Finger_03_%283986242135%29.jpg/600px-India_-_Koyambedu_Market_-_Ladies_Finger_03_%283986242135%29.jpg",
"width": 600,
"height": 450
},
"pageimage": "India_-_Koyambedu_Market_-_Ladies_Finger_03_(3986242135).jpg"
}
}
},
"limits": {
"pageimages": 500
}
}
类.dart
class Herbslist {
String batchcomplete;
Continue herbslistContinue;
Query query;
Limits limits;
Herbslist({
this.batchcomplete,
this.herbslistContinue,
this.query,
this.limits,
});
factory Herbslist.fromJson(Map<String, dynamic> json) => Herbslist(
batchcomplete: json["batchcomplete"] == null ? null : json["batchcomplete"],
herbslistContinue: json["continue"] == null ? Continue(gcmcontinue:'0',continueContinue: '') : Continue.fromJson(json["continue"]),
query: json["query"] == null ? null : Query.fromJson(json["query"]),
limits: json["limits"] == null ? null : Limits.fromJson(json["limits"]),
);
Map<String, dynamic> toJson() => {
"batchcomplete": batchcomplete == null ? null : batchcomplete,
"continue": herbslistContinue == null ? null : herbslistContinue.toJson(),
"query": query == null ? null : query.toJson(),
"limits": limits == null ? null : limits.toJson(),
};
}
class Continue {
String gcmcontinue;
String continueContinue;
Continue({
this.gcmcontinue,
this.continueContinue,
});
factory Continue.fromJson(Map<String, dynamic> json) => Continue(
gcmcontinue: json["gcmcontinue"] == null ? null : json["gcmcontinue"],
continueContinue: json["continue"] == null ? null : json["continue"],
);
Map<String, dynamic> toJson() => {
"gcmcontinue": gcmcontinue == null ? null : gcmcontinue,
"continue": continueContinue == null ? null : continueContinue,
};
}
class Limits {
int pageimages;
Limits({
this.pageimages,
});
factory Limits.fromJson(Map<String, dynamic> json) => Limits(
pageimages: json["pageimages"] == null ? null : json["pageimages"],
);
Map<String, dynamic> toJson() => {
"pageimages": pageimages == null ? null : pageimages,
};
}
class Query {
Map<String, Page> pages;
Query({
this.pages,
});
factory Query.fromJson(Map<String, dynamic> json) => Query(
pages: json["pages"] == null ? null : Map.from(json["pages"]).map((k, v) => MapEntry<String, Page>(k, Page.fromJson(v))),
);
Map<String, dynamic> toJson() => {
"pages": pages == null ? null : Map.from(pages).map((k, v) => MapEntry<String, dynamic>(k, v.toJson())),
};
}
class Page {
int pageid;
int ns;
String title;
Thumbnail thumbnail;
String pageimage;
Page({
this.pageid,
this.ns,
this.title,
this.thumbnail,
this.pageimage,
});
factory Page.fromJson(Map<String, dynamic> json) => Page(
pageid: json["pageid"] == null ? null : json["pageid"],
ns: json["ns"] == null ? null : json["ns"],
title: json["title"] == null ? null : json["title"],
thumbnail: json["thumbnail"] == null ? Thumbnail(source:'',width:0,height:0) : Thumbnail.fromJson(json["thumbnail"]),
pageimage: json["pageimage"] == null ? null : json["pageimage"],
);
Map<String, dynamic> toJson() => {
"pageid": pageid == null ? null : pageid,
"ns": ns == null ? null : ns,
"title": title == null ? null : title,
"thumbnail": thumbnail == null ? null : thumbnail.toJson(),
"pageimage": pageimage == null ? null : pageimage,
};
}
class Thumbnail {
String source;
int width;
int height;
Thumbnail({
this.source,
this.width,
this.height,
});
factory Thumbnail.fromJson(Map<String, dynamic> json) => Thumbnail(
source: json["source"] == null ? null : json["source"],
width: json["width"] == null ? null : json["width"],
height: json["height"] == null ? null : json["height"],
);
Map<String, dynamic> toJson() => {
"source": source == null ? null : source,
"width": width == null ? null : width,
"height": height == null ? null : height,
};
}
解决方案
进行这些更改并尝试:
class _HerbsState extends State<Herbs> {
List pages; // add this
....
下一个:
@override
void initState() {
pages = []; // add this
if (gcm == null) {
gcm = '';
this.fetchPost(gcm);
} else {
this.fetchPost(gcm);
}
_scrollController.addListener(_scrollListener);
super.initState();
}
最后:
FutureBuilder<Herbslist>(
future: fetchPost(gcm),
builder: (context, snapshot) {
if (snapshot.hasData) {
List pages = snapshot.data.query.pages.values.toList(); // remove this line
pages.addAll(snapshot.data.query.pages.values); // add this line
...
推荐阅读
- android - androidx 迁移后,Android Studio 应用程序未安装在模拟器上
- javascript - jQuery 文件未在 Visual Studio 中连接
- vue.js - 在自定义组件上使用时 v-model 和 .sync 有什么区别
- r - 使用 MLE 方法估计指数分布的 lambda
- azure - 将构建文件夹发布到 wwwroot 后,Web 应用程序未更新
- spring-data-jpa - 如何防止 Spring 子类化实现存储库接口的类?
- r - 使用 dplyr 重新采样和循环不起作用
- python - 尝试在按钮提交上调用 Django 视图并重定向到同一页面(重新加载)
- macos - 使用 AppleScript 和 Finder 转换图像
- node.js - 如何防止 webpack 捆绑 node_modules 文件夹 [ Webpack 4.40.2 ]