Flutter:带有嵌套导航的底部导航栏和更改选项卡时恢复根页面

时间:2021-05-16 18:52:22

标签: flutter flutter-bottomnavigation

我是 Flutter 开发的新手。我已经通过多个教程来了解底部导航栏。

我已经尝试过这些教程,但无法达到我的要求。 我遵循的教程:

  1. https://codewithandrea.com/articles/multiple-navigators-bottom-navigation-bar/
  2. https://medium.com/flutter/getting-to-the-bottom-of-navigation-in-flutter-b3e440b9386
  3. https://medium.com/@theboringdeveloper/common-bottom-navigation-bar-flutter-e3693305d2d

我个人喜欢第一个教程,因为有嵌套路由。

信息:

我有 3 个标签的底部导航:主页、日历、个人资料。

主页标签有一个屏幕:Screen2日历有一个屏幕:Screen3个人资料有一个屏幕:Screen4

问题

我的底部导航栏保持屏幕状态(这很好)。

主屏幕有一个按钮可以打开Screen2。当用户点击时,它会推动 Screen2。当用户点击日历(标签)时,用户会看到日历屏幕。现在,用户再次单击主页按钮(选项卡),用户会看到 Screen2。因为它是那条路线(家)的一部分。他应该只看到主屏幕的地方。

我只想重置它。基本上主屏幕应该推送主屏幕并弹出主页的所有子项。切换标签时。

代码:

main.dart

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MainScreen(),
    );
  }
}

main_screen.dart

class MainScreen extends StatefulWidget {
  MainScreen({Key key}) : super(key: key);

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

class _MainScreenState extends State<MainScreen> {
  int _selectedIndex = 0;

  List<GlobalKey<NavigatorState>> _navigatorKeys = [
    GlobalKey<NavigatorState>(),
    GlobalKey<NavigatorState>(),
    GlobalKey<NavigatorState>()
  ];

  List<Widget> _widgetOptions = <Widget>[
    HomePage(),
    CalendarPage(),
    ProfilePage(),
  ];

  Map<String, WidgetBuilder> _routeBuilders(BuildContext context, int index) {
    return {
      '/': (context) {
        return [
          HomePage(),
          CalendarPage(),
          ProfilePage(),
        ].elementAt(index);
      },
    };
  }


  Widget _buildOffstageNavigator(int index) {
    var routeBuilders = _routeBuilders(context, index);

    return Offstage(
      offstage: _selectedIndex != index,
      child: Navigator(
        key: _navigatorKeys[index],
        onGenerateRoute: (routeSettings) {
          return MaterialPageRoute(
            builder: (context) => routeBuilders[routeSettings.name](context),
          ); 
        },
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    return WillPopScope(
      onWillPop: () async {
        final isFirstRouteInCurrentTab =
        !await _navigatorKeys[_selectedIndex].currentState.maybePop();

        // let system handle back button if we're on the first route
        return isFirstRouteInCurrentTab;
      },
      child: Scaffold(
        backgroundColor: Colors.white,
        body: SafeArea(
          child: Stack(
            children: [
              _buildOffstageNavigator(0),
              _buildOffstageNavigator(1),
              _buildOffstageNavigator(2),
            ],
          ),
        ),
        bottomNavigationBar: BottomNavigationBar(
          currentIndex: _selectedIndex,
          showSelectedLabels: false,
          showUnselectedLabels: false,
          items: [
            BottomNavigationBarItem(
              icon: Icon(
                Feather.home,
                color: Colors.grey[300],
              ),
              label: 'HOME',
              activeIcon: Icon(
                Feather.home,
                color: Colors.purple[300],
              ),
            ),
            BottomNavigationBarItem(
              icon: Icon(
                FontAwesome.calendar,
                color: Colors.grey[300],
              ),
              label: 'CALENDAR',
              activeIcon: Icon(
                FontAwesome.calendar,
                color: Colors.purple[300],
              ),
            ),
            BottomNavigationBarItem(
              icon: Icon(
                EvilIcons.user,
                color: Colors.grey[300],
                size: 36,
              ),
              label: 'PROFILE',
              activeIcon: Icon(
                EvilIcons.user,
                color: Colors.purple[300],
                size: 36,
              ),
            ),
          ],
          onTap: (index) {
            setState(() {
              _selectedIndex = index;
            });
          },
        ),
      ),
    );
  }
}

home_page.dart

class HomePage extends StatefulWidget {
  HomePage();

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

class _HomePageState extends State<HomePage> {
  @override
  Widget build(BuildContext context) {
    return Container(
        color: Colors.lightBlueAccent,
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          crossAxisAlignment: CrossAxisAlignment.stretch,
          children: <Widget>[
            Container(
              child: Text(
                'Screen 1',
                style: TextStyle(color: Colors.white, fontSize: 20),
              ),
              margin: EdgeInsets.all(16),
            ),
            FlatButton(
              onPressed: () {
                // Navigator.push(context, MaterialPageRoute(
                //   builder: (context) => Screen2()
                // ));

                Navigator.push(context, PageRouteBuilder(pageBuilder: (_,__,___) => Screen2()));
              },
              child: Text('Go to next screen'),
              color: Colors.white,
            ),
          ],
        ));
  }
}

calendar_page.dart

class CalendarPage extends StatefulWidget {
  CalendarPage({Key key}) : super(key: key);

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

class _CalendarPageState extends State<CalendarPage> {
  @override
  Widget build(BuildContext context) {
    return Container(
      color: Colors.red,
      child: Center(
        child: FlatButton(
          onPressed: (){
            Navigator.push(context, MaterialPageRoute(
                builder: (context) => Screen3()
            ));
          },
          child: Text('Go to next screen'),
          color: Colors.white,
        ),
      ),
    );
  }
}

如果有人能指出我的方向,我将不胜感激。提前致谢。

要求: 有标签,每个标签都有各自的屏幕(ScreenX-> ScreenY-> ScreenN)。当切换选项卡时,它应该弹出标签的所有子项。我希望这是可以理解的(对不起,我的英语不好)。

我在这里遗漏了什么?

0 个答案:

没有答案