从Navigator Flutter正确弹出屏幕

时间:2020-08-22 11:35:30

标签: flutter flutter-navigation

使用Navigator.popUntil返回到我需要返回的屏幕时遇到麻烦。

该应用是网页的一部分,屏幕/导航结构为: HomePage推动MainScreen(第一个应用程序屏幕),该屏幕使用导航栏浏览应用程序的屏幕,其中一个是PromotionsScreen

然后PromotionScreen用:推到ChooseProductScreen

                                                  Navigator.push(
                                                    context,
                                                    MaterialPageRoute(
                                                      settings: RouteSettings(
                                                        name: 'PromotionsScreen'
                                                      ),
                                                      builder: (_) =>
                                                          BlocProvider.value(
                                                            value: BlocProvider.of<
                                                                PromotionBloc>(
                                                                context),
                                                            child: ChooseProductScreen(
                                                              user: widget.user,
                                                              cityDb: widget.cityDb,
                                                              regionDb: widget.regionDb,
                                                              countryDb: widget.countryDb,
                                                            ),
                                                          ),
                                                    ),
                                                  );

然后ChooseProductScreen用:推送到NewEditPromotionScreen

                                     Navigator.push(


                                     //  Navigator.pushReplacement( // Bloc event isn't sent from NewEditPromotionScreen


                                    context,
                                      MaterialPageRoute(
                                          settings: RouteSettings(
                                              name: 'ChooseProductScreen'
                                          ),
                                        builder: (_) =>
                                            BlocProvider.value(
                                              value: BlocProvider
                                                  .of<
                                                  PromotionBloc>(
                                                  context),
                                              child:
                                              NewEditPromotionScreen(
                                                  type: 'New',
                                                  user: widget
                                                      .user,
                                                  cityDb:
                                                  widget.cityDb,
                                                  regionDb: widget
                                                      .regionDb,
                                                  countryDb: widget
                                                      .countryDb),
                                            ),
                                      ),
                                    );

现在从NewEditPromotionScreen开始,我要回到PromotionsScreen

// pop CircularProgressIndicator Dialog
                  Navigator.of(context, rootNavigator: true).pop(context);



                  // pop the screen
//                  Navigator.popUntil(context, (route) => route.isFirst); // pops to HomePage
//                  Navigator.popUntil(context, (route) => route.settings.name == 'PromotionsScreen'); // pops to white screen
//                  Navigator.popUntil(context, ModalRoute.withName('PromotionsScreen')); // pops only to ChooseProductScreen

                  Navigator.pushAndRemoveUntil(
                      context,
                      MaterialPageRoute(builder: (BuildContext context) => PromotionsScreen()), // Screen is not in NavigationBar 
                      (route) => false);

我尝试过:

Navigator.popUntil(context, (route) => route.isFirst);,但这会弹出到网页HomeScreen

我尝试在推到RouteSettings时在PromotionsScreen的{​​{1}}中给'PromotionsScreen'命名,然后使用ChooseProductScreen但只弹出直到Navigator.popUntil(context, ModalRoute.withName('PromotionsScreen'));

这是因为“ PromotionsScreen”是推送路线的名称 到ChooseProductScreen,因此ChooseProductScreen实际上按预期工作吗? 如果是这种情况,如何导航到popUntil而不是弹出菜单,因为导航栏是由NavigationBar管理的?

我也尝试过:

PromotionsScreen

但这会在导航栏中显示屏幕。

您能以任何一种方式发现我正在穿的衣服吗?

非常感谢您的帮助。

1 个答案:

答案 0 :(得分:0)

尝试并实现了自定义function WrapWithProviders({ children }) { return ( <Provider store={store}> <MemoryRouter> <Switch> {children} </Switch> </MemoryRouter> </Provider> ); } const wrapper = mount(<TestComponent />, { wrappingComponent: WrapWithProviders, }); ,如此处接受的答案所示 Flutter persistent navigation bar with named routes?

因此,我的Navigator从将所有屏幕显示在列表中,并使用at索引作为主体,改为使用导航器的命名路线,而使用了MainScreen的{​​{1}}回调,我根据索引推送适当的名称路由。

Navigation Bar

现在从onTap开始,直到我需要的正确的路由名称为止:


Scaffold(
              key: _navigatorKey,
//              body: screens[_currentIndex],
            body: Navigator(
              key: _navigatorKey,
              initialRoute: '/',
              onGenerateRoute: (RouteSettings settings) {
                WidgetBuilder builder;
                // Manage your route names here
                switch (settings.name) {
                  case '/':
                    builder = (BuildContext context) => OrganizerScreen(
                      user: widget.user,
                      userLocation: widget.userLocation,
                      cityUser: widget.cityUser,
                      regionUser: widget.regionUser,
                      countryUser: widget.countryUser,
                      cityDb: widget.cityDb,
                      regionDb: widget.regionDb,
                      countryDb: widget.countryDb,
                    );
                    break;
                  case '/ProductsScreen':
                    builder = (BuildContext context) => ProductsScreen(
                      user: widget.user,
                      cityDb: widget.cityDb,
                      regionDb: widget.regionDb,
                      countryDb: widget.countryDb,
                    );
                    break;
                  case '/PromotionsScreen':
                    builder = (BuildContext context) => PromotionsScreen(
                      user: widget.user,
                      cityDb: widget.cityDb,
                      regionDb: widget.regionDb,
                      countryDb: widget.countryDb,
                    );
                    break;
                  case '/BookingScreen':
                    builder = (BuildContext context) => BookingScreen(
                      user: widget.user,
                      cityDb: widget.cityDb,
                      regionDb: widget.regionDb,
                      countryDb: widget.countryDb,
                    );
                    break;
                  case '/OrderScreen':
                    builder = (BuildContext context) => OrderScreen(
                      user: widget.user,
                      cityDb: widget.cityDb,
                      regionDb: widget.regionDb,
                      countryDb: widget.countryDb,
                    );
                    break;
                  case '/OpeningTimesScreen':
                    builder = (BuildContext context) => OpeningTimesScreen(
                      user: widget.user,
                      coordinates: widget.userLocation,
                      cityDb: widget.cityDb,
                      regionDb: widget.regionDb,
                      countryDb: widget.countryDb,
                    );
                    break;
                  case '/UserProfileScreen':
                    builder = (BuildContext context) => UserProfileScreen(
                      user: widget.user,
                      userLocation: widget.userLocation,
                      cityUser: widget.cityUser,
                      regionUser: widget.regionUser,
                      countryUser: widget.countryUser,
                    );
                    break;
                  default:
                    throw Exception('Invalid route: ${settings.name}');
                }
                // You can also return a PageRouteBuilder and
                // define custom transitions between pages
                return MaterialPageRoute(
                  builder: builder,
                  settings: settings,
                );
              },
            ),
              bottomNavigationBar: BottomNavigationBar(
                backgroundColor: Colors.transparent,
                showUnselectedLabels: true,
                unselectedItemColor: Colors.black38,
                selectedItemColor: Colors.orange,
//                onTap: onTabTapped,
                onTap: (int index) {
                  setState(() {
                    _currentIndex = index;

                    switch(index){
                      case 0:
                        _navigatorKey.currentState.pushNamed('/');
                        break;
                      case 1:
                        _navigatorKey.currentState.pushNamed('/ProductsScreen');
                        break;
                      case 2:
                        _navigatorKey.currentState.pushNamed('/PromotionsScreen');
                        break;
                      case 3:
                        _navigatorKey.currentState.pushNamed('/BookingScreen');
                        break;
                      case 4:
                        _navigatorKey.currentState.pushNamed('/OrderScreen');
                        break;
                      case 5:
                        _navigatorKey.currentState.pushNamed('/OpeningTimesScreen');
                        break;
                      case 6:
                        _navigatorKey.currentState.pushNamed('/UserProfileScreen');
                        break;
                      default:
                        throw Exception('Invalid route ');
                    }
                  });
                },
                currentIndex: _currentIndex,
                items: [
                  new BottomNavigationBarItem(
                    icon: Icon(Icons.calendar_today),
                    title: new AutoSizeText(
                      AppLocalizations.instance.text('Organizer'),
                      style: TextStyle(fontSize: 10, color: Colors.black54),
                      minFontSize: 5,
                      maxLines: 1,
                    ),
                  ),
                  new BottomNavigationBarItem(
                    icon: Icon(Icons.store), // .list),
                    title: new AutoSizeText(
                      AppLocalizations.instance.text('Shop'),
                      style: TextStyle(fontSize: 10, color: Colors.black54),
                      minFontSize: 5,
                      maxLines: 1,
                    ),
                  ),
                  new BottomNavigationBarItem(
                    icon: Icon(Icons.store), // .list),
                    title: new AutoSizeText(
                      AppLocalizations.instance.text('Promotions'),
                      style: TextStyle(fontSize: 10, color: Colors.black54),
                      minFontSize: 5,
                      maxLines: 1,
                    ),
                  ),
                  new BottomNavigationBarItem(
                    icon: new Icon(Icons.build),
                    title: new AutoSizeText(
                      AppLocalizations.instance.text('Bookings'),
                      style: TextStyle(fontSize: 10, color: Colors.black54),
                      minFontSize: 5,
                      maxLines: 1,
                    ),
                  ),
                  new BottomNavigationBarItem(
                    icon: new Icon(Icons.shopping_basket),
                    title: new AutoSizeText(
                      AppLocalizations.instance.text('Orders'),
                      style: TextStyle(fontSize: 10, color: Colors.black54),
                      minFontSize: 5,
                      maxLines: 1,
                    ),
                  ),
                  new BottomNavigationBarItem(
                    icon: Icon(Icons.access_time),
                    title: AutoSizeText(
                        AppLocalizations.instance.text('Opening Times'),
                        style: TextStyle(fontSize: 10, color: Colors.black54),
                        minFontSize: 5,
                        maxLines: 1),
                  ),
                  new BottomNavigationBarItem(
                    icon: Icon(Icons.person_outline),
                    title: AutoSizeText(
                        AppLocalizations.instance.text('User profile'),
                        style: TextStyle(fontSize: 10, color: Colors.black54),
                        minFontSize: 5,
                        maxLines: 1),
                  ),
//                  new BottomNavigationBarItem(
//                    icon: Icon(Icons.settings),
//                    title: AutoSizeText('Settings',
//                        style: TextStyle(fontSize: 10, color: Colors.black54),
//                        minFontSize: 5,
//                        maxLines: 1),
//                  ),
                ],
              ),

            ),

我仍然不明白为什么在使用NewEditPromotionScreen // working properly to go to PromotionsScreen : Navigator.popUntil(context, (route) => route.settings.name == '/PromotionsScreen'); // or to initial route: Navigator.popUntil(context, ModalRoute.withName('/')); // Not working Navigator.popUntil(context, ModalRoute.withName('/PromotionsScreen')); // nor Navigator.popUntil(context, ModalRoute.withName('PromotionsScreen')); popUntil失败(与初始路由一起使用),并且需要使用PromotionsScreen参数检查才能工作。