![](/img/trans.png)
[英]How Do I Use RefreshIndicator with a FutureBuilder in Flutter?
[英]How to use RefreshIndicator to update FutureBuilder state?
我正在使用FutureBuilder来显示从服务器加载的数据。 我只想在应用程序启动时显示加载 state 一次,这就是我从 initState 调用 API 的原因。 我从服务器获得的数据可能会发生变化,为了反映 UI 的变化,我正在使用refreshIndicator 。 问题是我无法想出更新 state 的解决方案。
class MyHomePage extends StatefulWidget {
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
GlobalKey<RefreshIndicatorState> _refreshIndicatorKey =
GlobalKey<RefreshIndicatorState>();
Future<List<Photo>> _photosServer;
@override
void initState() {
super.initState();
_photosServer = ApiRest.getPhotos();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: RefreshIndicator(
key: _refreshIndicatorKey,
onRefresh: () {
_refreshIndicatorKey.currentState.show();
await getPhotosFromServer();
...
},
child: FutureBuilder(
future: _photosServer,
builder: (BuildContext context, snapshot) {
if (snapshot.data == null) {
return Center(
child: Text('Loading...'),
);
}
return ListView.builder(
itemCount: snapshot.data.length,
itemBuilder: (BuildContext context, index) => ListTile(
title: Text(snapshot.data[index].title),
),
);
},
),
),
);
}
}
在onRefresh function 中,我使用以下代码在从服务器获取数据时显示 RefreshIndicator。
onRefresh: () {
_refreshIndicatorKey.currentState.show();
await getPhotosFromServer();
...
}
我还应该做些什么来处理这个问题?
你可以有一个单独的List<Photo>
变量,它可以由 FutureBuilder 或 RefreshIndicator 更新,并执行以下操作:
class _MyHomePageState extends State<MyHomePage> {
GlobalKey<RefreshIndicatorState> _refreshIndicatorKey =
GlobalKey<RefreshIndicatorState>();
List<Photo> _photosList;
Future<void> _initPhotosData;
@override
void initState() {
super.initState();
_initPhotosData = _initPhotos();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: FutureBuilder(
future: _initPhotosData,
builder: (BuildContext context, snapshot) {
switch (snapshot.connectionState) {
case ConnectionState.none:
case ConnectionState.waiting:
case ConnectionState.active:
{
return Center(
child: Text('Loading...'),
);
}
case ConnectionState.done:
{
return RefreshIndicator(
key: _refreshIndicatorKey,
onRefresh: _refreshPhotos,
child: ListView.builder(
itemCount: _photosList.length,
itemBuilder: (BuildContext context, index) => ListTile(
title: Text(_photosList[index].title),
),
));
}
}
},
),
);
}
Future<void> _initPhotos() async {
final photos = await ApiRest.getPhotos();
_photosList = photos;
}
Future<void> _refreshPhotos() async {
final photos = await ApiRest.getPhotos();
setState(() {
_photosList = photos;
});
}
}
onRefresh: () {
return Future(() { setState(() {}); });
},
在您的 RefreshIndicator 将刷新子 FutureBuilder
为了刷新数据并显示刷新指示器,只需等待结果然后更新未来:
onRefresh: () async {
final results = await getPhotosFromServer();
setState(() {
_photosServer = Future.value( results );
});
},
我创建了一个小部件来处理这种情况
您可以像 FutureBuilder 一样简单地使用它,除了您必须提供 function 调用而不是 Future
import 'package:flutter/material.dart';
class RefreshIndicatorFutureBuilder<T> extends StatefulWidget {
const RefreshIndicatorFutureBuilder({
super.key,
required this.future,
required this.builder,
});
final Future<T> Function() future;
final Widget Function(BuildContext, AsyncSnapshot<T> snapshot) builder;
@override
State<RefreshIndicatorFutureBuilder<T>> createState() =>
_RefreshIndicatorFutureBuilderState<T>();
}
class _RefreshIndicatorFutureBuilderState<T>
extends State<RefreshIndicatorFutureBuilder<T>> {
late Future<T> Function() future = widget.future;
@override
Widget build(BuildContext context) {
return RefreshIndicator(
onRefresh: () async {
setState(() {
future = widget.future;
});
},
child: FutureBuilder<T>(future: future(), builder: widget.builder),
);
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.