使用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
但这会在导航栏中显示屏幕。
您能以任何一种方式发现我正在穿的衣服吗?
非常感谢您的帮助。
答案 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
参数检查才能工作。