如何使用 Flutter 的 onWillpop 实现 BottomNavigationBar 页面过渡?

How do I make BottomNavigationBar page transition with Flutter's onWillpop?

我在 Flutter 项目中使用 BottomNavigationBar。 这个问题针对第 30 行“//TODO:回到 FirstTab”。 当用户位于 SecondTab 或 ThirdTab 并且按下 Android 设备中的 BackButton 时,我希望用户转到 FirstTab。 现在,在 onWillpopScope 中,有一个可以弹出的过程。当用户在 NextPage 时使用。 然后,当用户不在 FirstTab(SecondTab 或 ThirdTab)中且不在 NextTab 中时,我想将他移动到 onWillpopScope 中的 FirstTab。 (我想强制 BottomNavigationBar 切换。) 我该如何描述呢?请告诉我。

import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart';

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

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  List<GlobalKey<NavigatorState>> navigatorKeys = [
    GlobalKey<NavigatorState>(),
    GlobalKey<NavigatorState>(),
    GlobalKey<NavigatorState>(),
  ];

  @override
  Widget build(BuildContext context) {
    int currentIndex = 0;
    return MaterialApp(
      home: WillPopScope(
        onWillPop: () async {
          final isFirstRouteInCurrentTab = await navigatorKeys[currentIndex].currentState.maybePop();

          if (isFirstRouteInCurrentTab) {
            if (currentIndex != 0) {
              //TODO: back to the FirstTab
              
              return false;
            }
          }

          return isFirstRouteInCurrentTab;
        },
        child: CupertinoTabScaffold(
          tabBar: CupertinoTabBar(
            items: <BottomNavigationBarItem>[
              BottomNavigationBarItem(label: 'Home', icon: Icon(Icons.home)),
              BottomNavigationBarItem(label: 'Search', icon: Icon(Icons.search)),
              BottomNavigationBarItem(label: 'Setting', icon: Icon(Icons.settings)),
            ],
            onTap: (index) {
              // back home only if not switching tab
              if (currentIndex == index) {
                switch (index) {
                  case 0:
                    navigatorKeys[index].currentState.popUntil((route) => route.isFirst);
                    break;
                  case 1:
                    navigatorKeys[index].currentState.popUntil((route) => route.isFirst);
                    break;
                  case 2:
                    navigatorKeys[index].currentState.popUntil((route) => route.isFirst);
                    break;
                }
              }
              currentIndex = index;
            },
            currentIndex: currentIndex,
          ),
          tabBuilder: (BuildContext context, int index) {
            return CupertinoTabView(
              navigatorKey: navigatorKeys[index],
              builder: (BuildContext context) {
                switch (index) {
                  case 0:
                    return FirstTab();
                  case 1:
                    return SecondTab();
                  case 2:
                    return ThirdTab();
                  default:
                    return FirstTab();
                }
              },
            );
          },
        ),
      ),
    );
  }
}

class FirstTab extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return CupertinoPageScaffold(
      navigationBar: CupertinoNavigationBar(
        middle: Text('first page now'),
      ),
      backgroundColor: Colors.red[200],
      child: Center(
        child: CupertinoButton(
          child: const Text('Next'),
          onPressed: () {
            Navigator.of(context).push(CupertinoPageRoute(builder: (context) => NextPage()));
          },
        ),
      ),
    );
  }
}

//Different color from Firsttab
class SecondTab extends StatelessWidget {}

//Different color from Firsttab
class ThirdTab extends StatelessWidget {}

class NextPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return CupertinoPageScaffold(
      navigationBar: CupertinoNavigationBar(
        middle: Text('second page now'),
      ),
      backgroundColor: Colors.white,
      child: Center(
        child: CupertinoButton(
          child: const Text('Back'),
          onPressed: () {
            Navigator.of(context).pop();
          },
        ),
      ),
    );
  }
}

第一步 int currentIndex = 0; 至 class 成员

下一个

//TODO: back to the FirstTab
setState((){
   currentIndex = 0;
});

你可以试试看docs.

我会在这里继续。首先你需要创建一个控制器

final CupertinoTabController _controller = CupertinoTabController();

并像这样添加到您的 CupertinoTabScaffold

CupertinoTabScaffold(
      ...
      controller: _controller,
)

最后你把页面改成这样:

_controller.index = 0,

(这就是 Flutter 中 get 和 set 的工作方式)