【发布时间】:2019-07-08 09:51:07
【问题描述】:
我是新来的颤振。我需要我的应用程序包含 4 个不同的小部件。每个小部件都有自己的数据,可以在 initState 方法中从服务器读取。第一次加载布局时调用 initState 并从服务器获取数据。所以一切正常,除了我注意到如果我单击非相邻选项卡会再次调用 initState。
例如:如果我点击了 Tab 3 然后是 Tab 2,在第一次加载它们之后,之前的状态加载正常并且不会再次调用 initState。但是,如果我点击 Tab 4,然后点击 Tab 1 或 Tab 2,在第一次加载它们后,会再次调用两个选项卡的 initState 并转到服务器重新获取数据。
我尝试在 initState 中使用 if (this.mounted),但它被评估为 true,如果未按相同顺序选择选项卡,仍会再次从服务器获取数据。 p>
import 'package:flutter/material.dart';
import 'app_layouts.dart';
void main() {
runApp(MaterialApp(home: HomePage2()));
}
class HomePage2 extends StatefulWidget {
@override
_HomePage2State createState() => _HomePage2State();
}
class _HomePage2State extends State<HomePage2> with SingleTickerProviderStateMixin {
static final List<MyTab> myTabs = [
MyTab(tab: Tab(icon: Icon(Icons.home)), tabView: SimpleTabView()),
MyTab(tab: Tab(icon: Icon(Icons.calendar_today)), tabView: SimpleTab2View()),
MyTab(tab: Tab(icon: Icon(Icons.message)), tabView: SimpleTabView()),
MyTab(tab: Tab(icon: Icon(Icons.note)), tabView: SimpleTab2View()),
];
var _tabController;
@override
void initState() {
super.initState();
_tabController = TabController(length: myTabs.length, vsync: this);
_tabController.addListener(() {
//I added a custom tab controller, as I need to be notified with tab change events
});
}
@override
void dispose() {
_tabController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Test Tab Issue'),
bottom: TabBar(
tabs: myTabs.map((tab) => tab.tab).toList(),
controller: _tabController,
),
),
body: TabBarView(
children: myTabs.map((tab) => tab.tabView).toList(),
controller: _tabController,
),
);
}
}
class MyTab {
Tab tab;
Widget tabView;
MyTab({this.tab, this.tabView});
}
class SimpleTabView extends StatefulWidget {
@override
_SimpleTabViewState createState() => _SimpleTabViewState();
}
class _SimpleTabViewState extends State<SimpleTabView> with AutomaticKeepAliveClientMixin {
bool isDoingTask = true;
@override
void initState() {
super.initState();
print('initState called ...');
if (this.mounted) {
this.getTask();
}
}
@override
Widget build(BuildContext context) {
super.build(context);
return new Stack(
children: <Widget>[
Text('Tab view'),
Loader(showLoading: isDoingTask),
],
);
}
void getTask() async {
setState(() {
isDoingTask = true;
});
print("${new DateTime.now()} Pause for 3 seconds");
await new Future.delayed(const Duration(seconds: 3));
if (!this.mounted) return null;
setState(() {
isDoingTask = false;
});
}
@override
bool get wantKeepAlive => true;
}
//Exactly the same as SimpleTabView except the class name
class SimpleTab2View extends StatefulWidget {....
我希望不会再次调用 initState 方法,因为我已经在使用 AutomaticKeepAliveClientMixin,并且它已经被第一次调用了。
【问题讨论】:
-
如果您切换到
master频道,这将按预期工作。修复似乎还没有登陆stable。 -
感谢您的回复。您能否分享该主分支的链接?如果有任何期望什么时候会去
stable,如果发布了? -
您可以在终端中使用命令
flutter channel master切换到master频道。不知道什么时候稳定。 -
感谢您的建议。这行得通。等待一天的稳定版本。