【问题标题】:How to handle back navigation in Bottom Navigation in Flutter如何在 Flutter 的底部导航中处理后退导航
【发布时间】:2020-12-17 22:32:15
【问题描述】:

我正在制作一个颤振应用程序,其中流程是这样的:启动画面,它将检查用户是否登录。如果未登录,则转到登录屏幕,否则转到主屏幕。主屏幕具有三个选项卡的底部导航,每个选项卡都有自己的导航器,在每个导航器中,某些屏幕可能不会显示底部栏。所以我一直编码到现在。

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter',
      home: Splash(),
      routes: <String, WidgetBuilder>{
        '/main_tab':  (context) => new MainScreen(),
         '/login':  (context) => new Login(),
      },
    );
  }
}

现在有底部标签的 MainScreen 是这样的。

class MainScreen extends StatefulWidget {
  @override
  _MainScreenState createState() => new _MainScreenState();
}

class _MainScreenState extends State<MainScreen>{
  final _navigatorKey = GlobalKey<NavigatorState>();
  int _selectedIndex = 0;
  int _lastIndex = 0;

  void _onItemTapped(int index) {
     if(index == 0) _navigatorKey.currentState.pushNamed('/');
     else if(index == 1) _navigatorKey.currentState.pushNamed('/page1');
     else if(index == 2) _navigatorKey.currentState.pushNamed('/page2');
    setState(() {
      _lastIndex = _selectedIndex;
      _selectedIndex = index;
    });
  }
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: WillPopScope(
        onWillPop: () async {
          if(_selectedIndex == 0) SystemNavigator.pop();
          else if (_navigatorKey.currentState.canPop()) {
             _navigatorKey.currentState.pop();
             setState(() {
               _selectedIndex = _lastIndex;
              // _lastIndex = _selectedIndex;
             });
              return false;
           }
          return true;
        },
        child: Navigator(
          key: _navigatorKey,
          initialRoute: '/',
            onGenerateRoute: (RouteSettings settings) {
              WidgetBuilder builder;
              // Manage your route names here
              switch (settings.name) {
                case '/':
                  builder = (BuildContext context) => Page1();
                  break;
                case '/page1':
                  builder = (BuildContext context) => Page2();
                  break;
                case '/page2':
                  builder = (BuildContext context) => Page3();
                  break;
                default:
                  throw Exception('Invalid route: ${settings.name}');
              }
              return MaterialPageRoute(
                builder: builder,
                settings: settings,
              );
            }
        ),
      ),
      bottomNavigationBar:BottomNavigationBar(
        items: const <BottomNavigationBarItem>[
          BottomNavigationBarItem(
            icon: Icon(Icons.home),
            title: Text('Home'),
          ),
          BottomNavigationBarItem(
            icon: Icon(Icons.business),
            title: Text('Business'),
          ),
          BottomNavigationBarItem(
            icon: Icon(Icons.school),
            title: Text('School'),
          ),
        ],
        currentIndex: _selectedIndex,
        selectedItemColor: Colors.amber[800],
        onTap: _onItemTapped,
        type: BottomNavigationBarType.fixed,
      ),
    );
  }
}

根据我的要求,一切正常。要导航到没有底栏的屏幕,我遇到了一些问题,但我通过使用rootnavigator:true 并在MainApp() 中声明该路线来管理它。 现在,担心的是,当我按下返回按钮时,屏幕弹出工作正常,但它并没有改变底部栏选择的索引。所以我把逻辑放在 willPop 中,但那不能正常工作。 所以请告诉我如何处理底部栏中的后按,并且它应该更改底部栏的选定选项卡。

【问题讨论】:

    标签: flutter navigation


    【解决方案1】:

    在我参与的一个项目中,我必须这样做。应用程序有底部导航,一些页面正在使用根导航器推送。为了处理后退动作,我这样做了:

    WillPopScope(
      onWillPop: () async {
        bool canPop = await appFlows[currentTabIndex]
            .navigatorKey
            .currentState
            .maybePop();
        if (canPop) {
          return false;
        }
        if (currentTabIndex != 0) {
          navigateToTab(0);
          return false;
        }
        return true;
      },
      child: ...,
    )
    

    这样,如果选项卡的导航堆栈有多个屏幕,则会弹出该屏幕。如果用户在选项卡的根屏幕并按回,用户将被发送到主选项卡。如果用户在主选项卡的根屏幕并按下回,Flutter 将处理并退出应用程序。

    【讨论】:

      猜你喜欢
      • 2021-04-06
      • 2019-02-18
      • 2018-10-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-02-25
      • 2020-02-07
      相关资源
      最近更新 更多