Flutter 多次调用initstate()在选项卡之间切换
多次调用initstate()在选项卡之间切换 我有4个标签在我的标签巴拉,B,C和D 案例(1)如果我像从选项卡A切换到选项卡B那样切换选项卡,则工作正常 案例(2)但如果我转到选项卡A到C,那么选项卡B的initstate()调用了两次 个案(1)的结果 颤振:一个 颤振:BFlutter 多次调用initstate()在选项卡之间切换,flutter,dart,flutter-layout,Flutter,Dart,Flutter Layout,多次调用initstate()在选项卡之间切换 我有4个标签在我的标签巴拉,B,C和D 案例(1)如果我像从选项卡A切换到选项卡B那样切换选项卡,则工作正常 案例(2)但如果我转到选项卡A到C,那么选项卡B的initstate()调用了两次 个案(1)的结果 颤振:一个 颤振:B void main() => runApp(MyApp()); class MyApp extends StatelessWidget { // This widget is the root of you
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> with SingleTickerProviderStateMixin{
TabController _controller;
void initState() {
super.initState();
_controller = TabController(length: 4, vsync: this);
_controller.addListener(_handleSelected);
}
bool alarm = false;
// Function for handle tap event of tab
void _handleSelected() async {
}
Widget build(BuildContext context) {
return DefaultTabController(
length: 4,
child: Scaffold(
appBar: AppBar(
bottom: TabBar(
controller: _controller,
tabs: [
Tab(text: "A"),
Tab(text: "B"),
Tab(text: "C"),
Tab(text: "D"),
],
),
actions: [
Switch(
value: alarm,
onChanged: (value) {
},
activeTrackColor: Color(0xffff6b6b),
activeColor: Color(0xffff0000),
),
],
),
body: TabBarView(
controller: _controller,
children: [
A(),
B(),
C(),
D(),
],
),
),
);
}
}
个案结果(二)
颤振:一个
颤振:B
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> with SingleTickerProviderStateMixin{
TabController _controller;
void initState() {
super.initState();
_controller = TabController(length: 4, vsync: this);
_controller.addListener(_handleSelected);
}
bool alarm = false;
// Function for handle tap event of tab
void _handleSelected() async {
}
Widget build(BuildContext context) {
return DefaultTabController(
length: 4,
child: Scaffold(
appBar: AppBar(
bottom: TabBar(
controller: _controller,
tabs: [
Tab(text: "A"),
Tab(text: "B"),
Tab(text: "C"),
Tab(text: "D"),
],
),
actions: [
Switch(
value: alarm,
onChanged: (value) {
},
activeTrackColor: Color(0xffff6b6b),
activeColor: Color(0xffff0000),
),
],
),
body: TabBarView(
controller: _controller,
children: [
A(),
B(),
C(),
D(),
],
),
),
);
}
}
颤振:C
颤振:B
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> with SingleTickerProviderStateMixin{
TabController _controller;
void initState() {
super.initState();
_controller = TabController(length: 4, vsync: this);
_controller.addListener(_handleSelected);
}
bool alarm = false;
// Function for handle tap event of tab
void _handleSelected() async {
}
Widget build(BuildContext context) {
return DefaultTabController(
length: 4,
child: Scaffold(
appBar: AppBar(
bottom: TabBar(
controller: _controller,
tabs: [
Tab(text: "A"),
Tab(text: "B"),
Tab(text: "C"),
Tab(text: "D"),
],
),
actions: [
Switch(
value: alarm,
onChanged: (value) {
},
activeTrackColor: Color(0xffff6b6b),
activeColor: Color(0xffff0000),
),
],
),
body: TabBarView(
controller: _controller,
children: [
A(),
B(),
C(),
D(),
],
),
),
);
}
}
void main()=>runApp(MyApp());
类MyApp扩展了无状态小部件{
//此小部件是应用程序的根。
@凌驾
小部件构建(构建上下文){
返回材料PP(
标题:“颤振演示”,
主题:主题数据(
主样本:颜色。蓝色,
),
主页:MyHomePage(标题:“颤振演示主页”),
);
}
}
类MyHomePage扩展StatefulWidget{
MyHomePage({Key,this.title}):超级(Key:Key);
最后的字符串标题;
@凌驾
_MyHomePageState createState()=>\u MyHomePageState();
}
类_MyHomePageState使用SingleTickerProviderStateMixin扩展状态{
TabController\u控制器;
void initState(){
super.initState();
_controller=TabController(长度:4,vsync:this);
_controller.addListener(_handleSelected);
}
布尔报警=假;
//用于处理选项卡的点击事件的函数
void\u handleSelected()异步{
}
小部件构建(构建上下文){
返回DefaultTabController(
长度:4,
孩子:脚手架(
appBar:appBar(
底部:选项卡栏(
控制器:_控制器,
选项卡:[
选项卡(文本:“A”),
选项卡(文本:“B”),
选项卡(文本:“C”),
选项卡(文本:“D”),
],
),
行动:[
开关(
值:报警,
一旦更改:(值){
},
activeTrackColor:Color(0xffff6b6b),
activeColor:Color(0xffff0000),
),
],
),
正文:选项卡视图(
控制器:_控制器,
儿童:[
A(),
B(),
C(),
D(),
],
),
),
);
}
}
您可以使用IndexedStack
小部件来解决此类问题
在\u MyHomePageState
中,使用一个变量来管理所选页面的索引
class _MyHomePageState extends State<MyHomePage> with SingleTickerProviderStateMixin{
int _selectedPage;
/////
Your code
/////
}
现在在\u handleSelected()
方法handle中,从控制器获取最新的页面索引,并使用setState更新选项卡栏
void _handleSelected () async {
int index = _controller.page ;// get index from controller (I am not sure about exact parameter name for selected index) ;
setState((){
_selectedPage = index;
});
}
要使有状态小部件保持活动状态(而不是重建或重新渲染),可以使用
automatickepaliveclientmixin
。通过这种方式,您可以通过更改“wantKeepAlive”参数轻松决定需要重建哪个小部件
以下是a类的一个示例:
class A extends StatefulWidget {
@override
_AState createState() => _AState();
}
class _AState extends State<A> with AutomaticKeepAliveClientMixin{
bool _isLoading;
@override
void initState() {
super.initState();
Future.delayed(Duration(seconds: 3)).then((_){
setState(() {
_isLoading = false;
});
});
}
@override
Widget build(BuildContext context) {
return Center(
child: _isLoading == false ?
Text("A")
: CircularProgressIndicator(),
);
}
@override
bool get wantKeepAlive => true;
}
A类扩展了StatefulWidget{
@凌驾
_AState createState()=>_AState();
}
类_AState使用AutomaticEpaLiveClientMixin扩展状态{
bool_卸载;
@凌驾
void initState(){
super.initState();
未来。延迟(持续时间(秒:3))。然后(){
设置状态(){
_isLoading=false;
});
});
}
@凌驾
小部件构建(构建上下文){
返回中心(
子项:_isLoading==false?
文本(“A”)
:CircularProgressIndicator(),
);
}
@凌驾
bool get wantKeepAlive=>true;
}
您找到解决方案了吗?请尝试用PageView
小部件替换TabBarView