Навигатор флаттера 2.0: Добавьте анимацию для RouterDelegate.setNewRoutePath

#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")),  ],  )  )  );  } }