[英]Flutter: How to switch to a page which already is in the Navigator stack?
我有一個抽屜,里面有通往不同搜索頁面的命名路線。 推送路線導航到搜索頁面。 搜索頁面中的每個項目都會導航到詳細信息頁面。 后退按鈕會彈出詳細信息頁面,我又回到了搜索頁面。 此方案正確使用了導航器堆棧。
但是如何在多個搜索頁面之間切換? 我只能彈出一個搜索頁面,然后再推送另一個。
我正在尋找的另一個用例是在詳細信息頁面之間切換。 在這種情況下,導航器將保存(按此順序):第一個搜索頁面、第一個詳細信息頁面、第二個搜索頁面、第二個詳細信息頁面。 我想在兩個詳細信息頁面之間切換。
有什么方法可以窺視 Navigator 堆棧並將窺視的條目帶到堆棧的頂部?
多個導航器在這里有幫助嗎? 我可以在導航器之間切換嗎?
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
GlobalKey<NavigatorState> navKey = GlobalKey( );
void main( ) => runApp( MyApp( ) );
class MyApp extends StatelessWidget {
final Provider<MyMenu> menuProvider = Provider(
builder: ( context ) => MyMenu( ) );
@override
Widget build( BuildContext context ) {
return MultiProvider(
child: MaterialApp(
title: 'My App',
home: MyHomePage( ),
navigatorKey: navKey,
routes: {
routePage1: ( context ) => Page1( ),
routePage2: ( context ) => Page2( ),
},
theme: ThemeData( primarySwatch: Colors.blue, ),
),
providers: [
menuProvider,
], );
}
}
class MyMenu extends StatelessWidget {
@override
Widget build( BuildContext context ) {
String currentRoute = getCurrentRouteName( );
return Drawer( child: ListView( children: <Widget>[
ListTile(
leading: Icon( Icons.home ),
onTap: ( ) => navigateTo( context, routePage1 ),
selected: currentRoute == routePage1,
title: Text( "Page 1" ),
),
ListTile(
onTap: ( ) => navigateTo( context, routePage1 ),
selected: currentRoute == routePage1,
title: Text( "Page 1" ),
),
ListTile(
onTap: ( ) => navigateTo( context, routePage2 ),
selected: currentRoute == routePage2,
title: Text( "Page 2" ),
),
],
),
);
}
}
String getCurrentRouteName( ) {
String currentRouteName;
navKey.currentState.popUntil( ( route ) {
currentRouteName = route.settings.name;
return true;
} );
return currentRouteName;
}
void navigateTo( BuildContext context, String namedRoute, { Object arguments } ) {
// --- Close drawer menu if open
if ( Scaffold
.of( context )
.isDrawerOpen ) {
navKey.currentState.pop( );
}
// --- No navigation if target page already active
String currentRoute = getCurrentRouteName( );
if ( currentRoute == namedRoute ) return;
// --- Navigate to target
if ( currentRoute == "/" ) {
navKey.currentState.pushNamed( namedRoute, arguments: arguments );
} else {
navKey.currentState.popAndPushNamed( namedRoute, arguments: arguments );
}
}
class MyAppBar extends StatelessWidget implements PreferredSizeWidget {
@override
Widget build( BuildContext context ) {
String currentRoute = getCurrentRouteName( );
return AppBar(
leading: MenuButton( ),
title: Text( 'my app -> ${currentRoute}' ), );
}
@override
Size get preferredSize => Size.fromHeight( kToolbarHeight );
}
class MenuButton extends StatelessWidget {
@override
Widget build( BuildContext context ) {
return IconButton(
icon: Icon( Icons.menu ),
onPressed: ( ) {
ScaffoldState scaffold = Scaffold.of( context );
if ( scaffold.isDrawerOpen ) {
navKey.currentState.pop( );
} else {
scaffold.openDrawer( );
}
},
);
}
}
class MyHomePage extends StatelessWidget {
@override
Widget build( BuildContext context ) {
return Scaffold(
appBar: MyAppBar( ),
body: Center(
child: Text( "This is the Homepage" ),
),
drawer: Provider.of<MyMenu>( context ),
);
}
}
const String routePage1 = '/page1';
class Page1 extends StatelessWidget {
@override
Widget build( BuildContext context ) {
return Scaffold(
appBar: MyAppBar( ),
body: Center(
child: Text( "This is Page 1" ),
),
drawer: Provider.of<MyMenu>( context ),
);
}
}
const String routePage2 = '/page2';
class Page2 extends StatelessWidget {
@override
Widget build( BuildContext context ) {
return Scaffold(
appBar: MyAppBar( ),
body: Center(
child: Text( "This is Page 2" ),
),
drawer: Provider.of<MyMenu>( context ),
);
}
}
創建一個字段類型的小部件並替換菜單項上的這些小部件,如下面的代碼。
enum DrawerSelection {
home,
cropFamilies,
cropCalender,
favorites,
settings,
notes,
contactUs,
disclaimer
}
class _MyHomePage extends State<MyHomePage> {
DrawerSelection _drawerSelection = DrawerSelection.home;
Widget _appBarTitle = Text("Home");
Widget _currentWidget = MainWidget();
ListTile(
selected: _drawerSelection == DrawerSelection.home,
title: Text('Home'),
leading: Icon(Icons.home),
onTap: () {
_drawerSelection = DrawerSelection.home;
Navigator.pop(context);
_currentWidget = MainWidget();
setState(() {
_appBarTitle = Text("Home");
});
},
),
ListTile(
selected: _drawerSelection == DrawerSelection.cropFamilies,
title: Text('Crop families فصل کا خاندان'),
leading: Icon(Icons.nature),
onTap: () {
_drawerSelection = DrawerSelection.cropFamilies;
Navigator.pop(context);
_currentWidget = CropFamiliesWidget();
setState(() {
_appBarTitle = Text("Crop families فصل کا خاندان");
});
},
),
在所有菜單項中執行此操作。 如果您不想在抽屜菜單中顯示所選顏色,則可以忽略抽屜選擇。
更新如果您想在堆棧中導航回所需的路線,您可以使用 popUntil 方法,如下所示。 看這里
Navigator.popUntil(context, ModalRoute.withName('/login'));
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.