Flutter为什么在选项卡式界面中放置我的窗口小部件状态对象?

时间:2019-04-25 13:41:28

标签: flutter tabs dispose

我有一个使用DefaultTabController的选项卡式Flutter界面,该界面有3页,每个页面都是有状态的小部件。我似乎可以在前两个选项卡之间切换,但是当我将选项卡切换到第3页时,将丢弃第一页的状态对象。随后的状态更新(使用setState())将失败。

我已经为第一页覆盖了状态对象的dispose()方法,以便在处理时打印出一条消息。当我点击第三个标签时,它就会被丢弃。我找不到有关Flutter为何布置状态对象的文档。 (在生命周期上投入很多,但没有逐步完成的原因。)

我认为,设置标签并没有什么异常。

 @override
  Widget build(BuildContext context) {
    return new MaterialApp(

      home: DefaultTabController(
        length: 3,
        child: Scaffold(
          appBar: AppBar(
            title: Text(title),
            bottom: TabBar(
              tabs: [
                // Use these 3 icons on the tab bar.
                Tab(icon: Icon(Icons.tune)),
                Tab(icon: Icon(Icons.access_time)),
                Tab(icon: Icon(Icons.settings)),
              ],
            ),
          ),
          body: TabBarView(
            children: [
              // These are the 3 pages relating to to the tabs.
              ToolPage(),
              TimerPage(),
              SettingsPage(),
            ],

页面本身非常简单。没有动画。只是开关和滑块等。我想想我与所看到的代码示例的唯一不同之处在于,我已使主应用程序小部件成为有状态的,我扩展了选项卡页面以支持wantKeepAlive()和我重写了wantKeepAlive以将其设置为true(这可能会有所帮助),然后从外部对象在前两个选项卡上调用setState(),而Android Studio会用弱警告对其进行标记。从此应用打开的Websocket读取到远程服务器时,前两个页面上的状态会更新。经过进一步的测试,我注意到只有在我从第一页切换到第三页时,它才会发生。从第一到第二或从第二到第三不会触发处置。

我希望与StatefulWidget关联的State对象仍然存在,并且与wantKeepAlive = true不知道为什么单击第三个选项卡时会丢弃它,尤其是因为单击第二个选项卡时不会发生或从第二到第三。

1 个答案:

答案 0 :(得分:0)

发生这种情况是因为TabBarView并不总是显示所有标签。有些可能不在屏幕范围内。

在这种情况下,默认行为是Flutter将卸载这些小部件以优化资源。

可以使用Flutter称为“保持活动”来更改此行为。

最简单的方法是在标签中包含的AutomaticKeepAliveClientMixin子类上使用State mixin,例如:

class Foo extends StatefulWidget {
  @override
  _FooState createState() => _FooState();
}

class _FooState extends State<Foo> with AutomaticKeepAliveClientMixin {
  @override
  bool wantKeepAlive = true;

  @override
  Widget build(BuildContext context) {
    return Container();
  }
}

这告诉Flutter Foo离开屏幕时不应丢弃。