#flutter #flutter-web #navigator
Вопрос:
Я новичок в Flutter и в настоящее время пытаюсь настроить навигационную систему для своего первого приложения. Это работает — я могу переключаться между маршрутами с помощью Navigator.of(context).pushNamed()
или Navigator.of(context).pop()
и могу изменять историю навигации с помощью RouterDelegate.setNewRoutePath()
. Но когда setNewRoutePath
вызывается и RouterDelegate
перестраивается с новым значением для Navigator.pages
, при отображении нового маршрута не происходит анимации, что делает все это непоследовательным. Есть ли способ это исправить? Я использую Flutter 2.5.3.
Ниже приведен мой пример кода:
import 'package:flutter/material.dart'; import 'package:flutter/foundation.dart'; import 'dart:ui'; void main() { runApp(const MyApp()); } class MyApp extends StatelessWidget { const MyApp({Key? key}) : super(key: key); @override Widget build(BuildContext context) { return MaterialApp.router( title: 'Flutter Demo', theme: ThemeData( primarySwatch: Colors.blue, ), routeInformationParser: AppRouteInformationParser(), routerDelegate: AppRouterDelegate(), ); } } //Navigator 2.0 setup //Config type class AppRoute { //This might be extended in the future to hold more data late String route; AppRoute(this.route); } //Parser class AppRouteInformationParser extends RouteInformationParserlt;AppRoutegt;{ @override Futurelt;AppRoutegt; parseRouteInformation(RouteInformation routeInformation) { return SynchronousFuture(AppRoute(routeInformation.location ?? "/")); } } //Delegate class AppRouterDelegate extends RouterDelegatelt;AppRoutegt; { var _navigationHistory = ValueNotifierlt;Listlt;Pagegt;gt;([MaterialPage(child: FirstPage())]); @override Widget build(BuildContext context) { return ValueListenableBuilder( valueListenable: _navigationHistory, builder: (context, history, child) { return Navigator( key: UniqueKey(), pages: (history ?? []) as Listlt;Pagegt;, onPopPage: (route, result) =gt; route.didPop(result), onGenerateRoute: (routeSettings) { switch (routeSettings.name) { case "/subPage": return MaterialPageRoute(builder: (context) =gt; SecondPage()); break; case "/subPage/subPage": return MaterialPageRoute(builder: (context) =gt; ThirdPage()); break; } }, ); } ); } @override Futurelt;boolgt; popRoute() { return SynchronousFuture(true); } @override Futurelt;voidgt; setNewRoutePath(AppRoute route) { switch (route.route) { case "/subPage": _navigationHistory.value = [MaterialPage(child: FirstPage()), MaterialPage(child: SecondPage())]; break; case "/subPage/subPage": _navigationHistory.value = [MaterialPage(child: FirstPage()), MaterialPage(child: SecondPage()), MaterialPage(child: ThirdPage())]; break; default: _navigationHistory.value = [MaterialPage(child: FirstPage())]; } return SynchronousFuture(null); } @override void addListener(VoidCallback listener) {} @override void removeListener(VoidCallback listener) {} } //Pages class FirstPage extends StatelessWidget { @override Widget build (context) { return Scaffold( body: Center( child: Column( mainAxisSize: MainAxisSize.min, children: [ const Text("Page 1"), ElevatedButton(onPressed: () {Router.of(context).routerDelegate.setNewRoutePath(AppRoute("/subPage/subPage"));}, child: const Text("To page 3")), ElevatedButton(onPressed: () {Navigator.of(context).pushNamed("/subPage");}, child: const Text("To next page")), ], ) ) ); } } class SecondPage extends StatelessWidget { @override Widget build (context) { return Scaffold( body: Center( child: Column( mainAxisSize: MainAxisSize.min, children: [ const Text("Page 2"), ElevatedButton(onPressed: () {Navigator.of(context).pop();}, child: const Text("Go back")), ElevatedButton(onPressed: () {Navigator.of(context).pushNamed("/subPage/subPage");}, child: const Text("To next page")), ], ) ) ); } } class ThirdPage extends StatelessWidget { @override Widget build (context) { return Scaffold( body: Center( child: Column( mainAxisSize: MainAxisSize.min, children: [ const Text("Page 3"), ElevatedButton(onPressed: () {Navigator.of(context).pop();}, child: const Text("Go back")), ], ) ) ); } }