0

我正在开发一个应用程序,使用 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();
}

有没有办法不重置?

4

1 回答 1

1

编辑

正如@p2kr指出的那样,您在build函数中搞混了(因为您还拥有dispose要在函数外部定义的回调build),并且您使用CupertinoTabScaffold了文档所述的位置:

您必须侦听 onTap 回调并使用新的 currentIndex 调用 setState 以反映新的选择。这也可以通过使用 CupertinoTabScaffold 包装来自动完成。

取自这里。因此,如果您不使用CupertinoTabScaffold. 在您的情况下,您的课程应如下所示:

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',
        ),
    ],
),
于 2021-06-24T08:15:57.857 回答