I'm using Navigator 2.0 API to handle navigation in my app, and I have problem with top-most RouterDelegate
(the nested RouterDelegates
underneath it work fine). Depending on authentication state I want to show Splash Screen, Login Screen, or Home Screen. The logic works fine and pages change depending on provided state, but there are no page transitions shown, neither on Android and iOS. That's weird, because in nested navigators this problem does not occurr. I've tried using several different Page
classes, as well as changing page order in stack, but nothing seems to help - the transition animations seem to be completely ignored. Here's how my app structure looks like:
Main App definition:
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) => FutureBuilder(
future: AppInit.initApp(),
builder: (context, snapshot) {
if (snapshot.hasError) {
log(
"App init failed!",
level: Level.SEVERE.value,
error: snapshot.error,
stackTrace: snapshot.stackTrace,
);
}
return _app();
},
);
Widget _app() => MaterialApp(
supportedLocales: LocalizationConfig.supportedLocales,
localizationsDelegates: LocalizationConfig.localizationDelegates,
theme: LightTheme().themeData,
navigatorObservers: [
FirebaseAnalyticsObserver(
analytics: AppDependencies.firebaseAnalytics,
)
],
home: MultiRepositoryProvider(
providers: AppRepositoryProviders.list,
child: MultiBlocProvider(
providers: AppBlocProviders.list,
child: Router(
routerDelegate: AppRouter(),
backButtonDispatcher: RootBackButtonDispatcher(),
),
),
),
);
}
Any my AppRouter page construction looks like this:
@override
Widget build(BuildContext context) => BlocBuilder<AppNavigationCubit, AppNavigationState>(
builder: (context, state) => Navigator(
key: internalNavigatorKey,
onPopPage: (route, dynamic result) => _popPage(context, route, result),
pages: getPageStack(context, state),
),
);
List<Page> getPageStack(BuildContext context, AppNavigationState state) {
List<Page> pageStack = [];
if (state is AppNavigationInitial) {
pageStack.add(SlideTransitionPage<void>(
key: AppRoutes.splash.valueKey,
name: AppRoutes.splash.name,
child: const SplashScreen(),
));
}
if (state is AppNavigationLoggedOut) {
pageStack.add(SlideTransitionPage<void>(
key: AppRoutes.auth.valueKey,
name: AppRoutes.auth.name,
child: const AuthScreen(),
));
}
if (state is AppNavigationLoggedIn) {
pageStack.add(SlideTransitionPage<void>(
key: AppRoutes.home.valueKey,
name: AppRoutes.home.name,
child: const HomeScreen(),
));
}
return pageStack;
}
And my implementation that extends Page
(not sure if that has any impact, since default MaterialPage
also doesn't do transitions):
class SlideTransitionPage<T> extends Page<T> {
final Widget child;
final Duration duration;
const SlideTransitionPage({
required LocalKey? key,
required String name,
required this.child,
this.duration = const Duration(milliseconds: 350),
}) : super(key: key, name: name);
@override
Route<T> createRoute(BuildContext context) =>
PageBasedSlideTransitionRoute<T>(this);
}
class PageBasedSlideTransitionRoute<T> extends PageRoute<T> {
final SlideTransitionPage<T> page;
PageBasedSlideTransitionRoute(this.page) : super(settings: page);
@override
Color? get barrierColor => null;
@override
String? get barrierLabel => null;
@override
Duration get transitionDuration => page.duration;
@override
bool get maintainState => true;
@override
Widget buildPage(
BuildContext context,
Animation<double> animation,
Animation<double> secondaryAnimation,
) =>
SlideTransition(
position: animation.drive(Tween(
begin: const Offset(1.0, 0.0),
end: Offset.zero,
).chain(CurveTween(
curve: Curves.ease,
))),
child: (settings as SlideTransitionPage).child,
);
@override
Widget buildTransitions(
BuildContext context,
Animation<double> animation,
Animation<double> secondaryAnimation,
Widget child,
) =>
child;
}
Any suggestions what can be the reason behind it? All routers (f.e. one nested in HomeScreen
and AuthScreen
) perform transitions correctly. My guess is, the construction somehow causes the main router to recreate, instead of updating it's state and performing transitions, but I fail to find any solution or possible causes