假设我有这样的事情:
return FutureBuilder(
future: _loadingDeals,
builder: (BuildContext context, AsyncSnapshot snapshot) {
return RefreshIndicator(
onRefresh: _handleRefresh,
...
)
}
)
Run Code Online (Sandbox Code Playgroud)
在该_handleRefresh方法中,我要以编程方式触发FutureBuilder的重新运行。
有这样的事吗?
用例:
当用户按下时refreshIndicator,则_handleRefresh只需FutureBuilder重新运行即可。
编辑:
完整的代码段首尾相连,不包含刷新部分。我已改用StreamBuilder,该refreshIndicator零件如何适合所有零件?
class DealList extends StatefulWidget {
@override
State<StatefulWidget> createState() => new _DealList();
}
class _DealList extends State<DealList> with AutomaticKeepAliveClientMixin {
// prevents refreshing of tab when switch to
// Why? /sf/ask/3585709431/
bool get wantKeepAlive => true;
final RestDatasource api = new RestDatasource();
String token;
StreamController _dealsController;
@override
void initState() {
super.initState();
_dealsController = new StreamController();
_loadingDeals();
}
_loadingDeals() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
this.token = prefs.getString('token');
final res =
this.api.checkInterests(this.token).then((interestResponse) async {
_dealsController.add(interestResponse);
return interestResponse;
});
return res;
}
_handleRefresh(data) async {
SharedPreferences prefs = await SharedPreferences.getInstance();
final token = prefs.getString('token');
await this.api.checkInterests(token).then((interestResponse) {
_dealsController.add(interestResponse);
});
return null;
}
@override
Widget build(BuildContext context) {
super.build(context); // <-- this is with the wantKeepAlive thing
return StreamBuilder(
stream: _dealsController.stream,
builder: (BuildContext context, AsyncSnapshot snapshot) {
if (snapshot.hasError) {
...
}
if (snapshot.connectionState != ConnectionState.done) {
return Center(
child: CircularProgressIndicator(),
);
}
if (!snapshot.hasData &&
snapshot.connectionState == ConnectionState.done) {
return Text('No deals');
}
if (snapshot.hasData) {
return ListView.builder(
physics: const AlwaysScrollableScrollPhysics(),
itemCount: snapshot.data['deals'].length,
itemBuilder: (context, index) {
final Map deal = snapshot.data['deals'][index];
return ListTile(
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => DealsDetailPage(
dealDetail: deal,
),
),
);
},
title: Text(deal['name']),
subtitle: Text(deal['expires']),
);
},
),
}
},
);
}
}
Run Code Online (Sandbox Code Playgroud)
为什么不使用StreamBuilder和Stream而不是FutureBuilder?
像这样
class _YourWidgetState extends State<YourWidget> {
StreamController<String> _refreshController;
...
initState() {
super...
_refreshController = new StreamController<String>();
_loadingDeals();
}
_loadingDeals() {
_refreshController.add("");
}
_handleRefresh(data) {
if (x) _refreshController.add("");
}
...
build(context) {
...
return StreamBuilder(
stream: _refreshController.stream,
builder: (BuildContext context, AsyncSnapshot snapshot) {
return RefreshIndicator(
onRefresh: _handleRefresh(snapshot.data),
...
)
}
);
}
}
Run Code Online (Sandbox Code Playgroud)
我使用StreamBuilder用Flutter主要示例创建了一个Gist,请检查一下
使用 StreamBuilder 是一种解决方案,但是,要以编程方式触发 FutureBuilder,只需调用 setState,它就会重建 Widget。
return RefreshIndicator(
onRefresh: () {
setState(() {});
},
...
)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2641 次 |
| 最近记录: |