Dart 颤振以编程方式触发FutureBuilder
假设我有这样的东西:Dart 颤振以编程方式触发FutureBuilder,dart,flutter,Dart,Flutter,假设我有这样的东西: return FutureBuilder( future: _loadingDeals, builder: (BuildContext context, AsyncSnapshot snapshot) { return RefreshIndicator( onRefresh: _handleRefresh, ... ) } ) 在\u handleRefresh方法中,我希望以编程方式触发FutureBuilder
return FutureBuilder(
future: _loadingDeals,
builder: (BuildContext context, AsyncSnapshot snapshot) {
return RefreshIndicator(
onRefresh: _handleRefresh,
...
)
}
)
在\u handleRefresh
方法中,我希望以编程方式触发FutureBuilder的重新运行
有这样的事吗
用例:
当用户拉下刷新指示器
,则\u手柄刷新
只会使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? https://stackoverflow.com/q/51224420/1757321
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']),
);
},
),
}
},
);
}
}
类DealList扩展了StatefulWidget{
@凌驾
State createState()=>new_DealList();
}
类_DealList使用AutomaticEpaLiveClientMixin扩展状态{
//防止切换到时刷新选项卡
//为什么??https://stackoverflow.com/q/51224420/1757321
bool get wantKeepAlive=>true;
最终RestDatasource api=新RestDatasource();
字符串标记;
StreamController\u dealsController;
@凌驾
void initState(){
super.initState();
_dealsController=新的StreamController();
_loadingDeals();
}
_loadingDeals()异步{
SharedReferences prefs=等待SharedReferences.getInstance();
this.token=prefs.getString('token');
最终结果=
this.api.checkInterests(this.token).then((interestResponse)异步{
_dealsController.add(利息响应);
利息回报率;
});
返回res;
}
_handleRefresh(数据)异步{
SharedReferences prefs=等待SharedReferences.getInstance();
final token=prefs.getString('token');
等待这个.api.checkInterests(令牌)。然后((interestResponse){
_dealsController.add(利息响应);
});
返回null;
}
@凌驾
小部件构建(构建上下文){
super.build(context);//DealsDetailPage(
交易详情:交易,
),
),
);
},
标题:文本(交易['name']),
字幕:文本(交易['expires']),
);
},
),
}
},
);
}
}
为什么不使用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),
...
)
}
);
}
}
class\u YourWidgetState扩展状态{
StreamController\u刷新控制器;
...
initState(){
超级的。。。
_refreshController=新的StreamController();
_loadingDeals();
}
_loadingDeals(){
_刷新控制器。添加(“”);
}
_handleRefresh(数据){
如(x)项加上(“”);
}
...
构建(上下文){
...
返回流生成器(
流:_refreshController.stream,
生成器:(BuildContext上下文,异步快照){
返回刷新指示器(
onRefresh:_handleRefresh(snapshot.data),
...
)
}
);
}
}
我使用StreamBuilder创建了一个flatter主示例的要点,使用StreamBuilder是一个解决方案,但是,要以编程方式触发FutureBuilder,只需调用setState,它将重建小部件
return RefreshIndicator(
onRefresh: () {
setState(() {});
},
...
)
与StreamBuilder相比,我更喜欢FutureBuilder,因为我在使用Firestore进行我的项目,并且您会收到reads的账单,所以我的解决方案就是这样
_future??= getMyFuture();
shouldReload(){
setState(()=>_future = null)
}
FutureBuilder(
future: _future,
builder: (context, snapshot){
return Container();
},
)
任何需要您获取新数据的用户活动只需调用shouldlreload()OK。这是下一级代码:p。我会深呼吸,细细咀嚼。会让你知道事情的进展。看起来是这样,但事实并非如此!尝试一下,你会发现它是有效的。我使用StreamBuilder创建了一个关于颤振主示例的要点,请检查:在上面的示例中,您将
快照.data
发送回\u handleRefresh
方法。为什么?在\u handleRefresh
中,如果(x)什么是x
?snapshot.data
:如果不需要,不需要传递它<代码>如果(x)是必须触发刷新的条件。如果没有条件,您可以删除if
并调用\u refreshController。立即添加(“”
。您想要的不是@Feu所述的Future
,而是Stream
。为什么不直接使用setState
?@JonahWilliams我正在使用setState
,但它不起作用。这可能是因为我正在使用AutomaticKepaLiveClientMixin的,所以整个小部件不会在状态更改时重建。为什么?请看这里: