我是新手。我需要我的应用程序包含4个不同的小部件。每个小部件都有自己的数据,可以通过initState方法从服务器读取。第一次加载布局时,将调用initState并从服务器正常获取数据。因此,除了我注意到如果我单击非相邻选项卡时再次调用了initState之外,其他所有功能都正常工作。
例如:如果我单击选项卡3,然后单击选项卡2,则在第一次加载它们后,以前的状态会很好地加载,并且不会再次调用initState。但是,如果我单击选项卡4,然后单击选项卡1或选项卡2,则在第一次加载它们后,将再次调用两个选项卡的initState并转到服务器以重新获取数据。
我尝试在initState中使用 if(this.mount),但是它被评估为true,并且如果未按相同顺序选择选项卡,仍会再次从服务器获取数据。
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,并且它已经是第一次。