Я хочу розробити кнопку виходу, яка направить мене до маршруту входу та видалить всі інші маршрути з Navigator
. Здається, що документація не пояснює, як створити RoutePredicate
або мати будь-яку функцію removeAll.
Я хочу розробити кнопку виходу, яка направить мене до маршруту входу та видалить всі інші маршрути з Navigator
. Здається, що документація не пояснює, як створити RoutePredicate
або мати будь-яку функцію removeAll.
Відповіді:
Я зміг досягти цього за допомогою такого коду:
Navigator.of(context)
.pushNamedAndRemoveUntil('/login', (Route<dynamic> route) => false);
Секрет тут полягає у використанні RoutePredicate, який завжди повертає false (Route<dynamic> route) => false
. У цій ситуації він видаляє всі маршрути, крім нового /login
маршруту, який я просунув.
я можу зробити з таким фрагментом коду:
Navigator.of(context).pushAndRemoveUntil(MaterialPageRoute(builder: (context) =>
LoginScreen()), (Route<dynamic> route) => false),
якщо ви хочете видалити весь маршрут, що знаходиться під натиснутим маршрутом, RoutePredicate завжди повертає false , наприклад (Route route) => false .
Іншим рішенням є використання pushAndRemoveUntil()
. Щоб видалити всі інші маршрути, використовуйтеModalRoute.withName('/')
Navigator.pushAndRemoveUntil(
context,
MaterialPageRoute(builder: (BuildContext context) => Login()),
ModalRoute.withName('/')
);
Посилання: https://api.flutter.dev/flutter/widgets/NavigatorState/pushAndRemoveUntil.html
Якщо ви хочете повернутися до певного екрану, і ви не використовуєте іменований маршрутизатор, можна скористатися наступним підходом
Приклад:
Navigator.pushAndRemoveUntil(context,
MaterialPageRoute(builder: (BuildContext context) => SingleShowPage()),
(Route<dynamic> route) => route is HomePage
);
Якщо маршрут є HomePage, ви перевіряєте назву свого віджета.
Якщо ви використовуєте namedRoutes, ви можете зробити це, просто:
Navigator.pushNamedAndRemoveUntil(context, "/login", (Route<dynamic> route) => false);
Де "/ login" - це маршрут, який ви хочете просувати в стеку маршрутів.
Зверніть увагу, що:
Цей вислів видаляє всі маршрути зі стеку і робить натиснутий коренем.
Я не знаю, чому ніхто не згадав рішення за допомогою SchedularBindingInstance , хоча трохи пізно на вечірку, я думаю, це був би правильний спосіб зробити це, спочатку відповіли тут
SchedulerBinding.instance.addPostFrameCallback((_) async {
Navigator.of(context).pushNamedAndRemoveUntil(
'/login',
(Route<dynamic> route) => false);
});
Наведений вище код видаляє всі маршрути та навігації до '/ login', це також робить впевненим, що всі кадри відображаються перед переходом на новий маршрут, плануючи зворотний виклик
Це працює для мене. Насправді я працював з блоком, але моєю проблемою було блокування екрана входу. Після оновлення оновлення не проводилось. Він містив дані попередньої моделі. Навіть я ввів неправильний запис. Це йшло на головний екран.
Крок 1:
Navigator.of(context).pushNamedAndRemoveUntil(
UIData.initialRoute, (Route<dynamic> route) => false);
де,
UIData.initialRoute = "/" or "/login"
Крок 2:
Це працює, щоб оновити екран. Якщо ви працюєте з Bloc, це буде дуже корисно.
runApp(MyApp());
де,
MyApp() is the root class.
Код кореневого класу (тобто MyApp)
class MyApp extends StatelessWidget {
final materialApp = Provider(
child: MaterialApp(
title: UIData.appName,
theme: ThemeData(accentColor: UIColor().getAppbarColor(),
fontFamily: UIData.quickFont,
),
debugShowCheckedModeBanner: false,
//home: SplashScreen(),
initialRoute: UIData.initialRoute,
routes: {
UIData.initialRoute: (context) => SplashScreen(),
UIData.loginRoute: (context) => LoginScreen(),
UIData.homeRoute: (context) => HomeScreen(),
},
onUnknownRoute: (RouteSettings rs) => new MaterialPageRoute(
builder: (context) => new NotFoundPage(
appTitle: UIData.coming_soon,
icon: FontAwesomeIcons.solidSmile,
title: UIData.coming_soon,
message: "Under Development",
iconColor: Colors.green,
)
)));
@override
Widget build(BuildContext context) {
return materialApp;
}
}
void main() => runApp(MyApp());
Ось метод My Logout ,
void logout() async {
SharedPreferences preferences = await SharedPreferences.getInstance();
preferences.clear();
// TODO: we can use UIData.loginRoute instead of UIData.initialRoute
Navigator.of(context).pushNamedAndRemoveUntil(
UIData.initialRoute, (Route<dynamic> route) => false);
//TODO: It's working as refresh the screen
runApp(MyApp());
}
Не впевнений, чи правильно я це роблю
але це влаштовує мій варіант використання вискакування до віджета root
void popUntilRoot({Object result}) {
if (Navigator.of(context).canPop()) {
pop();
popUntilRoot();
}
}