问题:
我有2个选项卡使用Default Tabs Controller,如下所示:
Widget build(BuildContext context) {
return DefaultTabController(
length: 2,
child: Scaffold(
drawer: Menu(),
appBar: AppBar(
title: Container(
child: Text('Dashboard'),
),
bottom: TabBar(
tabs: <Widget>[
Container(
padding: EdgeInsets.all(8.0),
child: Text('Deals'),
),
Container(
padding: EdgeInsets.all(8.0),
child: Text('Viewer'),
),
],
),
),
body: TabBarView(
children: <Widget>[
DealList(),
ViewersPage(),
],
),
),
);
}
}
Run Code Online (Sandbox Code Playgroud)
这DealList()是一个StatefulWidget像这样建立的:
Widget build(BuildContext context) {
return FutureBuilder(
future: this.loadDeals(),
builder: (BuildContext context, AsyncSnapshot snapshot) {
print('Has error: ${snapshot.hasError}');
print('Has data: ${snapshot.hasData}');
print('Snapshot data: ${snapshot.data}');
return snapshot.connectionState == ConnectionState.done
? RefreshIndicator(
onRefresh: showSomething,
child: ListView.builder(
physics: const AlwaysScrollableScrollPhysics(),
itemCount: snapshot.data['deals'].length,
itemBuilder: (context, index) {
final Map deal = snapshot.data['deals'][index];
print('A Deal: ${deal}');
return _getDealItem(deal, context);
},
),
)
: Center(
child: CircularProgressIndicator(),
);
},
);
}
}
Run Code Online (Sandbox Code Playgroud)
有了上面的内容,每当我切换回DealList()选项卡时会发生什么:它重新加载.

有没有办法在完成一次后阻止重新运行FutureBuilder?(计划是让用户使用RefreshIndicator重新加载.所以更改选项卡不应该触发任何内容,除非用户明确这样做.)
Jon*_*ams 56
这里有两个问题,第一个:
当TabController切换选项卡时,它会卸载旧的小部件树以节省内存.如果要更改此行为,则需要混合AutomaticKeepAliveClientMixin到选项卡窗口小部件的状态.
class _DealListState extends State<DealList> with AutomaticKeepAliveClientMixin<DealList> {
@override
bool get wantKeepAlive => true;
@override
Widget build(BuildContext context) {
super.build(context); // need to call super method.
return /* ... */
}
}
Run Code Online (Sandbox Code Playgroud)
第二个问题是你使用的FutureBuilder- 如果你提供一个新Future的FutureBuilder,它不能告诉结果将与上次相同,所以它必须重建.(请记住,Flutter可能会将您的构建方法调用到一帧一次).
return FutureBuilder(
future: this.loadDeals(), // Creates a new future on every build invocation.
/* ... */
);
Run Code Online (Sandbox Code Playgroud)
相反,您希望将未来分配给initState中State类的成员,然后将此值传递给FutureBuilder.确保后续重建的未来是相同的.如果要强制State重新加载交易,您始终可以创建一个重新分配_loadingDeals成员和调用的方法setState.
Future<...> _loadingDeals;
@override
void initState() {
_loadingDeals = loadDeals(); // only create the future once.
super.initState();
}
@override
Widget build(BuildContext context) {
super.build(context); // because we use the keep alive mixin.
return new FutureBuilder(future: _loadingDeals, /* ... */);
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
10757 次 |
| 最近记录: |