首页 > 解决方案 > 为什么 Flutter 在选项卡式界面中处理我的小部件状态对象?

问题描述

我有一个使用 DefaultTabController 的选项卡式 Flutter 界面,它有 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 不明白为什么当我单击第三个选项卡时它会被释放,特别是因为当我单击第二个选项卡或从第二到第三。

标签: fluttertabsdispose

解决方案


发生这种情况是因为TabBarView并不总是显示所有选项卡。有些可能在屏幕边界之外。

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

这种行为可以通过 Flutter 所说的“保持活跃”来改变。

最简单的方法是在选项卡中包含的子类上使用AutomaticKeepAliveClientMixinmixin,如下所示:State

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

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

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

这告诉 FlutterFoo在离开屏幕时不应该被释放。


推荐阅读