Как проверить, какой текущий маршрут?
Я хочу перемещаться по разным Маршрутам, используя Ящик, хотя я не хочу открывать новый экземпляр Маршрута каждый раз, когда я нажимаю на него, если я уже на этом Маршруте, скорее я предпочел бы, чтобы в этом случае новый Маршрут был не открыт Это мой код до сих пор:
Widget build(BuildContext context){
return new Drawer(
child:
new ListView(
children: <Widget>[
new ListTile(
title: new Text("NewRoute"),
onTap: () {
Navigator.of(context).pop;
Navigator.of(context).pushNamed('/NewRoute');
}
)
)
)
}
Я хочу использовать условный оператор, чтобы проверить, находимся ли мы на определенном маршруте. Я знаю, что есть способ проверить, на каком маршруте мы сейчас находимся, с помощью isCurrent класса Route.
https://docs.flutter.io/flutter/widgets/Route/isCurrent.html
хотя я не уверен, как это реализовать.
Заранее спасибо!
Ответы
Ответ 1
Navigator
не показывает текущий маршрут.
Вместо этого вы можете использовать Navigator.popUntil(callback)
поскольку popUtil
переходит к popUtil
вызову текущего Route
, который включает его имя и прочее.
final newRouteName = "/NewRoute";
bool isNewRouteSameAsCurrent = false;
Navigator.popUntil(context, (route) {
if (route.settings.name == newRouteName) {
isNewRouteSameAsCurrent = true;
}
return true;
});
if (!isNewRouteSameAsCurrent) {
Navigator.pushNamed(context, newRouteName);
}
Ответ 2
Ответ Реми действительно помог мне, но если вы новичок во Флаттере/Дарт, как я, потребуется время, чтобы понять. Итак, вот моя версия с некоторыми дополнительными проверками и пояснительной документацией:
/// Navigates through the application. Only replaces the top Route if it is
/// different from the new Route. Always keeps the home page as base of the
/// Navigator stack. New screens are pushed on the Navigator stack. When the
/// user switches between non-home screens, the new screen replaces the old
/// screen. In this way, the stack of screens from the drawer is never higher
/// than 2. Returning to the HomeScreen is done by just popping the current
/// Route.
void _changeRoute(BuildContext context, String newRouteName) {
// Close drawer
Navigator.pop(context);
// Check current screen status
bool currentRouteIsHome = false;
bool currentRouteIsNewRoute = false;
Navigator.popUntil(context, (currentRoute) {
// This is just a way to access currentRoute; the top route in the
// Navigator stack.
if (currentRoute.settings.name == HomeScreen.ROUTE_NAME) {
currentRouteIsHome = true;
}
if (currentRoute.settings.name == newRouteName) {
currentRouteIsNewRoute = true;
}
// Return true so popUntil() pops nothing.
return true;
});
// Switch screen
if (!currentRouteIsNewRoute) {
// Only switch screen if new route is different from current route.
if (currentRouteIsHome) {
// Navigate from home to non-home screen.
Navigator.pushNamed(context, newRouteName);
} else {
if (newRouteName == HomeScreen.ROUTE_NAME) {
// Navigate from non-home screen to home.
Navigator.pop(context);
} else {
// Navigate from non-home screen to non-home screen.
Navigator.popAndPushNamed(context, newRouteName);
}
}
}
}
Обратите внимание, что эта реализация с pushNamed
и popAndPushNamed
требует, чтобы вы определяли имена Route
в вашем MaterialApp
верхнего уровня в аргументе popAndPushNamed
routes:
следующим образом:
new MaterialApp(
routes: <String, WidgetBuilder>{
// define the routes
YOUR_SCREEN_ROUTE_NAME: (BuildContext context) => new YourScreen(),
},
)
Ответ 3
Это должно дать вам точное название маршрута
import 'package:path/path.dart';
ModalRoute.of(context).settings.name
Чтобы избежать нулевого исключения, сделайте это
var route = ModalRoute.of(context);
if(route!=null){
print(route.settings.name);
}
Ответ 4
Я использую этот код.
*Route route = MaterialPageRoute(builder: (context) => Myinternet());
print(route.isCurrent);
if(route.isCurrent){
}*
Выход:
Показывает Всегда ложно текущая страница не найдена
Ответ 5
ModalRoute.of(context).settings.name
хороший API для решения этой проблемы, но его нельзя использовать в initState();
Ответ 6
Используйте следующий код, чтобы проверить, является ли маршрут наибольшим...
Route route = MaterialPageRoute(builder: (context) => WidgetName());
if(route.isCurrent){
}
Ответ 7
Это моё решение.
void redirect(screen){
Navigator.popUntil(context, (route) {
if ( route.settings.name != screen) {
Navigator.pushNamed(context, screen);
}
return true;
});
}
Ответ 8
для меня я использую самый ленивый самый простой способ, так как никакой ответ здесь не помог мне в основном маршруте, я просто использую класс ящика и передаю имя текущего маршрута конструктору ящика следующим образом:
class MyDrawer extends StatelessWidget {
final String currentRoute;
MyDrawer(this.currentRoute);
@override
Widget build(BuildContext context) {
return Drawer(
child: ListView(
children: <Widget>[
InkWell(
child: Text('secondRoute'),
onTap: () {
if (currentRoute != 'secondRoute')
Navigator.push(context,
MaterialPageRoute(builder: (context) => secondRoute()));
}),
InkWell(
child: Text('thirdRoute'),
onTap: () {
if (currentRoute != 'thirdRoute')
Navigator.push(context,
MaterialPageRoute(builder: (context) => thirdRoute()));
}),
и в маршрутах, где я вызываю класс MyDrawer, я передаю имя текущего маршрута
drawer: MyDrawer('secondRoute'),