flutter - 刷新 ListView.builder 时颤动它从开始而不是从 maxScrollExtent 点返回
问题描述
我是 Flutter 的新手,我遇到了一个问题。
到目前为止,我正在从 Web 服务异步(Json)获取数据。所以在构建方法中,我FutureBuilder
为 Scaffold 的 body 参数使用了一个小部件。并且它的 'builder' 参数(FutureBuilder
小部件)返回 aListView.builder
以显示数据。我也ScrollController
用于滚动。
是我达到最大滚动点的时候了,我再次调用该服务以获取下一页数据等等......
问题是,当我通过滚动“更改页面”时,它会正确显示数据,但它从第一行数据开始,而不是从我到达该maxScrollExtent
点的地方开始。
因此,如果第一个“快照”有 25 行,第二个有 15 行,那么当我转到第二个时,它从第 1 行开始,而不是从第 26 行开始,尽管数据行的总数是 40 正确。
结果我没有平滑的滚动。到目前为止,我已经被困了足够长的时间,我不知道我错过了什么。我是否必须使用页面存储键(我看到了颤振团队的视频,但我没有找到解决我的问题的优势)。有什么提示吗?下面是代码示例。
class _MyAppState extends State<MyApp> {
final ScrollController _controller = ScrollController();
@override
void initState() {
super.initState();
_controller.addListener(_scrollListener);
}
void _scrollListener() {
if (_controller.offset >= _controller.position.maxScrollExtent &&
!_controller.position.outOfRange) {
if (nextDataSet != null) {
print('nextDataSet = ' + nextDataSet);
setState(() {
inDataSet = nextDataSet;
});
} else {
print('nextDataSet = NULL');
}
}
Future<Post> fetchPost([String dataSet]) async {
...
return Post.fromJson(json.decode(utf8.decode(response.bodyBytes)));
}
Widget build(BuildContext context) {
return MaterialApp(
home: Builder(
builder: (context) => Scaffold(
...
body: FutureBuilder<Post>(
future: fetchPost(inDataSet),
builder: _buildList,
),
),
),
);
}
Widget _buildList(BuildContext context, AsyncSnapshot snapshot) {
... /*code that eventually fills the lists of strings
progressivePartyListSec, progressivePartyListThird*/
...
return ListData(controller: _controller, listEidosPerigr:
progressivePartyListSec, listPerigr: progressivePartyListThird );
}
}
class ListData extends StatelessWidget {
final ScrollController controller;
final List<String> listEidosPerigr;
final List<String> listPerigr;
ListData({this.controller,
this.listEidosPerigr,
this.listPerigr});
@override
Widget build(BuildContext context) {
return ListView.builder(
controller: controller,
itemCount: rowsSelected,
itemBuilder: (context, i) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
removeAllHtmlTags(listEidosPerigr[i]),
style: TextStyle(
fontWeight: FontWeight.bold, color: Colors.blue),
),
new RichText(
text: new TextSpan(
text: listPerigr[i].replaceAllMapped('<BR>', (Match m) => '').replaceAllMapped('<b>', (Match m) => '').replaceAllMapped('</b>', (Match m) => ''),
style: DefaultTextStyle.of(context).style,
),
),
]);
});
}
}
解决方案
经过一些研究,我在以下链接中找到了解决方案:Flutter:创建一次加载一个页面的 ListView
非常感谢 AbdulRahman AlHamali。
基本上,在我发布的上述代码中,我为 ListView.builder 使用了另一个参数,它是以下键:PageStorageKey('offset'),
最后,正如 AbdulRahman 在他的文章中所写,我在我的构建方法中使用 KeepAliveFutureBuilder 作为 FutureBuilder 的包装器...
body: KeepAliveFutureBuilder(
//child: FutureBuilder<Post>(
future: fetchPost(inDataSet),
builder: _buildList,
//),
),
推荐阅读
- push-notification - 在 swift 4 中使用 FCM 未收到 PushNotification
- linux - 每当设备插入我的计算机时如何自动运行“sudo modprobe -r ftdi_sio”
- css - 为类添加css
- c# - 控件的 ASP.NET Core 条件验证
- firebase - Firebase Analytics 自定义事件参数报告有(未设置)
- unity3d - 虚拟现实 SDK Oculus 无法初始化
- sorting - 在 Solr 中对截断的日期进行排序
- module - 在 Odoo 13 中,如何在没有开发人员模式的情况下使计划在员工模块中可见?
- excel - 将 excel 工作表导入 Guava Table
- kubernetes - nginx 入口控制器 0.26.1 在 GKE v1.14 上返回 504(连接到上游时超时)