CupertinoTabView 在热重载时重置

CupertinoTabView resets on Hot Reload

我正在使用 CupertinoApp 模型开发应用程序。我正在为应用程序使用 CupertinoTabView 模型。现在在开发过程中,选项卡索引会在热重载时重置。我尝试在选项卡控制器上设置状态,但它仍然会重置。

代码:

class HomePage extends StatefulWidget {
  @override
  _HomePageState createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  @override
  Widget build(BuildContext context) {
    CupertinoTabController _controller = CupertinoTabController();

    @override
    void dispose() {
      _controller.dispose();
      super.dispose();
    }

    List<Widget> tabs = [
      HomeScreen(_controller),
      PlaySearchScreen(),
      HomeScreen(_controller),
      ProfileScreen(),
    ];
    return CupertinoTabScaffold(
        controller: _controller,
        tabBar: CupertinoTabBar(
          items: [
            BottomNavigationBarItem(
              icon: Icon(CupertinoIcons.home),
              label: 'Home',
            ),
            BottomNavigationBarItem(
              icon: Icon(CupertinoIcons.play),
              label: 'Play Tennis',
            ),
            BottomNavigationBarItem(
              icon: Icon(CupertinoIcons.calendar),
              label: ' My Schedule',
            ),
            BottomNavigationBarItem(
              icon: Icon(CupertinoIcons.person),
              label: 'Profile',
            ),
          ],
        ),
        tabBuilder: (context, index) {
          return CupertinoTabView(
            builder: (ctx) {
              return GestureDetector(
                child: tabs[index],
                onTap: () => setState(
                  () => _controller.index = index,
                ),
              );
            },
          );
        });
  }
}

class HomeScreen extends StatefulWidget {
  HomeScreen(
    this.controller, {
    Key key,
  }) : super(key: key);

  final CupertinoTabController controller;

  @override
  _HomeScreenState createState() => _HomeScreenState();
}

有没有办法让它不重置?

编辑

正如 @p2kr 所指出的,你在 build 函数中混淆了(因为你也有dispose 回调,其中你想在 build 函数之外定义)并且你使用 CupertinoTabScaffold 文档指出:

You must listen to the onTap callbacks and call setState with a new currentIndex for the new selection to reflect. This can also be done automatically by wrapping this with a CupertinoTabScaffold.

取自 here。因此,如果您不使用 CupertinoTabScaffold,我的原始答案将适用。在您的情况下,您的 class 应该如下所示:

class _HomePageState extends State<HomePage> {
    // Placing the _controller as a property of your class
    // instead of a local variable inside your build method
    // which would be re-instantiated on every build call -
    // as in the case of hot reload
    CupertinoTabController _controller = CupertinoTabController();

    // Also setting the dispose function correctly outside
    // of the build function
    @override
    void dispose() {
        _controller.dispose();
        super.dispose();
    }

    @override
    Widget build(BuildContext context) {
        List<Widget> tabs = [
            HomeScreen(_controller),
            PlaySearchScreen(),
            HomeScreen(_controller),
            ProfileScreen(),
        ];

        ...

原版

CupertinoTabBar 有一个 currentIndex 属性 来维护选定的选项卡。因此,您需要在 _HomePageState:

中添加一个额外的 属性
class _HomePageState extends State<HomePage> {
    // Variable to maintain current tab index.
    // Setting it to 0 (first tab) as default here
    int _index = 0;

    ...
}

然后在实际的 CupertinoTabBar 中,我们添加设置 currentIndex 属性 并使用 onTap 回调相应地更新我们的 属性:

CupertinoTabBar(
    // Setting the index
    currentIndex: _index,
    // Callback to update our index once a tab is clicked
    onTap: (index) => setState(() => _index = index),
    items: [
        BottomNavigationBarItem(
            icon: Icon(CupertinoIcons.home),
            label: 'Home',
        ),
        BottomNavigationBarItem(
            icon: Icon(CupertinoIcons.play),
            label: 'Play Tennis',
        ),
        BottomNavigationBarItem(
            icon: Icon(CupertinoIcons.calendar),
            label: ' My Schedule',
        ),
        BottomNavigationBarItem(
            icon: Icon(CupertinoIcons.person),
            label: 'Profile',
        ),
    ],
),