2

我是 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)。And when tab is switched it should pop all the children of the tabs. 我希望这可以理解(对不起,我的英语不好)。

我在这里想念什么?

4

1 回答 1

0

所以逻辑是如果我从主屏幕(选项卡)移到任何其他选项卡。我应该清除堆栈(不是指小部件)。

假设您正在学习第一个教程。

有 3 个选项卡。主页日历个人资料

现在从主屏幕我添加了“ Screen2 ”。所以,现在我的 currentTab 是“ Home ”。如果我单击日历选项卡,我 selectedTtab 是“日历”。

我将从当前选项卡中弹出所有内容,直到遇到第一条路线。一旦完成,我将设置状态。

代码:


void _selectTab(TabItem tabItem) {
    if (tabItem == _currentTab) {
      _navigatorKeys[tabItem]?.currentState?.popUntil((route) => route.isFirst);
    } else {
      //! Added logic to Pop everything from Home tab, if any other tab is clicked
      if (_currentTab == TabItem.HOME) {
        _navigatorKeys[_currentTab]
            ?.currentState
            ?.popUntil((route) => route.isFirst);
      }
      setState(() => _currentTab = tabItem);
    }
  }

我从底部导航调用这个方法。

bottomNavigationBar: BottomNavigation(
          currentTab: _currentTab,
          onSelectTab: _selectTab,
        ),

希望这可以帮助。让我知道这是否足够。

于 2021-09-10T01:42:44.223 回答