Flutter 多次调用initstate()在选项卡之间切换

Flutter 多次调用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

多次调用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 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