Flutter Tabbar builds/rebuilds 切换第一个和最后一个标签时的中间标签

Flutter Tabbar builds/rebuilds the middle tab when switching between first and last tab

我在我的 flutter 应用中使用了一个简单的标签栏。我从 flutter website 借用了代码 并稍微更新以确保我可以使用 AutomaticKeepAliveClientMixin 保持每个选项卡的状态。这是我的代码:

import 'package:flutter/material.dart';

void main() {
  runApp(TabBarDemo());
}

class TabBarDemo extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: DefaultTabController(
        length: 3,
        child: Scaffold(
          appBar: AppBar(
            bottom: TabBar(
              tabs: [
                Tab(icon: Icon(Icons.directions_car)),
                Tab(icon: Icon(Icons.directions_transit)),
                Tab(icon: Icon(Icons.directions_bike)),
              ],
            ),
            title: Text('Tabs Demo'),
          ),
          body: TabBarView(
            children: [
              Page1(),
              Page2(),
              Page3(),
            ],
          ),
        ),
      ),
    );
  }
}

class Page1 extends StatefulWidget {
  @override
  _Page1State createState() => _Page1State();
}

class _Page1State extends State<Page1>
    with AutomaticKeepAliveClientMixin<Page1> {
  @override
  bool get wantKeepAlive => true;
  @override
  Widget build(BuildContext context) {
    super.build(context);
    print('p1');
    return Container(
      child: Center(
        child: Icon(Icons.directions_car),
      ),
    );
  }
}

class Page2 extends StatefulWidget {
  @override
  _Page2State createState() => _Page2State();
}

class _Page2State extends State<Page2>
    with AutomaticKeepAliveClientMixin<Page2> {
  @override
  bool get wantKeepAlive => true;
  @override
  Widget build(BuildContext context) {
    super.build(context);
    print('p2');
    return Container(
      child: Center(
        child: Icon(Icons.directions_transit),
      ),
    );
  }
}

class Page3 extends StatefulWidget {
  @override
  _Page3State createState() => _Page3State();
}

class _Page3State extends State<Page3>
    with AutomaticKeepAliveClientMixin<Page3> {
  @override
  bool get wantKeepAlive => true;
  @override
  Widget build(BuildContext context) {
    super.build(context);
    print('p3');
    return Container(
      child: Center(
        child: Icon(Icons.directions_bike),
      ),
    );
  }
}

如您所见,我有 3 个选项卡,每个选项卡只显示一个图标。问题是,当我在第一个和第三个选项卡(Page1 和 Page3)之间切换时,中间选项卡一直在重建,直到我切换到该选项卡(Page2)并且只有在那个时候它才不再重建。一旦在第一个和第三个选项卡之间切换(不切换到第二个选项卡),您可以在调试控制台中看到它一直在打印“p2”。

我怎样才能阻止这种行为?在选择选项卡之前,我不想构建它。

您可以通过像这样添加 const 关键字来避免重新构建小部件

TabBarView(
 children: [
    const Page1(),
    const Page2(),
    const Page3(),
   ],
),

为了将来参考,如果有人遇到这个问题,我在 Github here 上得到了很好的答案。