Правильно всплывающие экраны из Navigator Flutter

У меня проблемы с использованием 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.

Я попытался указать имя «PromotionsScreen» в RouteSettings в PromotionsScreen при нажатии на ChooseProductScreen, а затем использовал Navigator.popUntil(context, ModalRoute.withName('PromotionsScreen'));, но всплывает только до ChooseProductScreen.

Это потому, что «PromotionsScreen» - это имя маршрута, который продвигается к ChooseProductScreen, поэтому popUntil действительно работает должным образом? Если это так, как можно вместо этого перейти к PromotionsScreen, поскольку путь к нему управляется панелью навигации?

Я также пробовал:

Navigator.pushAndRemoveUntil(
                      context,
                      MaterialPageRoute(builder: (BuildContext context) => PromotionsScreen()),
                      (route) => false);

но при этом экран будет отображаться не на панели навигации ..

Можете ли вы определить, что я делаю в одежде?

Большое спасибо за помощь.


person Vincenzo    schedule 22.08.2020    source источник


Ответы (1)


Пробовал и реализовал пользовательский Navigator, как в принятом ответе здесь Постоянная панель навигации Flutter с именованным маршруты?.

Итак, мой MainScreen изменился с того, чтобы все мои экраны были в списке и использовались один в индексе в качестве тела, на использование вместо этого именованных маршрутов навигатора, а в обратном вызове 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 не работает при использовании ModalRoute.withName (который работает с начальным маршрутом) и для работы необходимо использовать проверку параметров route.settings.name.

person Vincenzo    schedule 22.08.2020