Set default transition for go_router in Flutter - flutter

as the docs from go_router describe, it is easy to set pageBuilder-Transitions for single pages.
However, I want to set the default PageTransition for all pages.
How do I set the default page transition with/for go_router in Flutter?
Single Page:
// this is the proposed method to do it for single pages
// how can i apply it to all pages without writing the same code?
GoRoute(
path: '/login',
builder: (context, state) => const LoginScreen(),
pageBuilder: (context, state) => CustomTransitionPage<void>(
key: state.pageKey,
child: const LoginScreen(),
transitionsBuilder: (context, animation, secondaryAnimation, child) =>
FadeTransition(opacity: animation, child: child),
),
),
Best regards

The go_router package does not support this at the moment, but to reduce code duplication, you can create a helper function that would apply the custom transition for your route, like:
CustomTransitionPage buildPageWithDefaultTransition<T>({
required BuildContext context,
required GoRouterState state,
required Widget child,
}) {
return CustomTransitionPage<T>(
key: state.pageKey,
child: child,
transitionsBuilder: (context, animation, secondaryAnimation, child) =>
FadeTransition(opacity: animation, child: child),
);
}
<...>
GoRoute(
path: '/login',
builder: (context, state) => const LoginScreen(),
pageBuilder: (context, state) => buildPageWithDefaultTransition<void>(
context: context,
state: state,
child: LoginScreen(),
),
),

The more correct way is inheritance from CustomTransitionPage.
class WebPage extends CustomTransitionPage {
WebPage({
LocalKey key,
... // other properties taken from `MaterialPage`
required Widget child
}) : super(
key: key,
transitionBuilder: (...) {
return FadeTransition(...);
}
child: child, // Here you may also wrap this child with some common designed widget
);
}
Then
GoRoute(
path: '/login',
pageBuilder: (context, state) => WebPage(
key: state.pageKey,
child: const LoginScreen(),
),
),

Related

GoRouter - Using ShellRoute properly in Flutter

I am using a ShellRoute within my GoRouter with those arguments:
final GoRouter _vamosRouter = GoRouter(
debugLogDiagnostics: true,
initialLocation: EventsPage.route,
errorBuilder: (_, __) => const ErrorPage(),
routes: [
GoRoute(
path: LoginPage.route,
builder: (_, __) => const LoginPage(),
// redirect: (context, state) => context.read<UserViewModel>().isSignedIn ? EventsPage.route : null, // ändert nix
),
ShellRoute(
navigatorKey: _rootNavigatorKey,
builder: (_, __, child) => RootPage(widget: child),
routes: <RouteBase>[
GoRoute(path: ProfilePage.route, builder: (_, __) => const ProfilePage()),
GoRoute(path: OrganizationPage.route, builder: (_, __) => const OrganizationPage()),
GoRoute(path: EventsPage.route, builder: (_, __) => const EventsPage()),
],
),
],
redirect: (BuildContext context, _) => context.read<UserViewModel>().isSignedIn ? null : LoginPage.route,
);
My Root Page looks like this:
class RootPage extends StatelessWidget {
const RootPage({required this.widget});
final Widget widget;
#override
Widget build(BuildContext context) {
return Scaffold(
body: Row(children: [const Sidebar(), Expanded(child: widget)]),
);
}
}
So the basic layout is: a sidebar on the left side, and the main widget on the right site.
Problem: when switching between pages (or the main widget), the whole (RootPage) screen is built up again. How can I switch between pages in the ShellRoute with just the widget on the right site being reloaded?

Go_Router Pass Object to new route

I want to pass object from the listview to the sub route. It seems no way to pass the object.
Is there any how to do it?
GoRouter routes(AuthBloc bloc) {
return GoRouter(
navigatorKey: _rootNavigatorKey,
routes: <RouteBase>[
GoRoute(
routes: <RouteBase>[
GoRoute(
path: loginURLPagePath,
builder: (BuildContext context, GoRouterState state) {
return const LoginPage();
},
),
GoRoute(
path: homeURLPagePath,
builder: (BuildContext context, GoRouterState state) =>
const HomePage(),
routes: <RouteBase>[
GoRoute(
path: feeURLPagePath,
name: 'a',
builder: (context, state) => FeePage(),
routes: [
/// Fee Details page
GoRoute(
name: 'b',
path: feeDetailsURLPagePath,
builder: (BuildContext context, GoRouterState state) =>
const FeeDetails(),
),
]),
],
),
],
path: welcomeURLPagePath,
builder: (BuildContext context, GoRouterState state) =>
const SplashPage(),
),
],
refreshListenable: GoRouterRefreshStream(bloc.stream),
debugLogDiagnostics: true,
initialLocation: welcomeURLPagePath,
},
);
}
The error says no initial match found for feeDetails!
Use extra parameter in context.goNamed()
Example:
Object:
class Sample {
String attributeA;
String attributeB;
bool boolValue;
Sample(
{required this.attributeA,
required this.attributeB,
required this.boolValue});}
Define GoRoute as
GoRoute(
path: '/sample',
name: 'sample',
builder: (context, state) {
Sample sample = state.extra as Sample; // -> casting is important
return GoToScreen(object: sample);
},
),
Call it as:
Sample sample = Sample(attributeA: "True",attributeB: "False",boolValue: false)
context.goNamed("sample",extra:sample );
Receive it as:
class GoToScreen extends StatelessWidget {
Sample? object;
GoToScreen({super.key, this.object});
#override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Text(
object.toString(),
style: const TextStyle(fontSize: 24),
)),
);
}
}

Navigation to the screen where I am now

I need to update all the widgets on the screen, for this I decided to just make navigation to the screen I'm currently on. But unfortunately nothing happens. Tell me, what's the problem?
I am using the go_router package.
routes -
final GoRouter _router = GoRouter(
routes: <GoRoute>[
GoRoute(
path: '/',
builder: (BuildContext context, GoRouterState state) => Splash() ,
),
GoRoute(
path: '/home',
builder: (BuildContext context, GoRouterState state) => const Home() ,
),
GoRoute(
path: '/login',
builder: (BuildContext context, GoRouterState state) => const Login() ,
),
GoRoute(
path: '/createPinCode',
builder: (BuildContext context, GoRouterState state) => CreatePinCode() ,
),
],
button -
onCompleted: (value) async {
pinCode = int.parse(value);
sharedPrefsSet(pinCode);
context.go('/createPinCode');
},
If you just want to clear your form textFields than rather than re-build entire page you can user clear() property of TextEditingController.
TextEditingController nameController = TextEditingController();
func clearAllData() {
nameController.clear();
emailController.clear();
}
Call this clearAllData() when user tap on submit form.

How to apply transition animation to the .go function using the go_router package

I am using the go_router package because I need the deep linking it provides. I applied animation transitions to some routes but they are static, so every time I go to that route, the same animation is going to trigger. I would like to change the animation when I do GoRouter.of(context).go('/inbox')
This is what I have right now:
final router = GoRouter(
initialLocation: '/inbox',
routes: <GoRoute>[
GoRoute(
path: '/inbox',
pageBuilder: (BuildContext context, GoRouterState state) {
return PageTransition.slideFromRight(
myChildWidget: Layout(
context: context,
state: state,
child: EmailPage(),
),
state: state,
);
},
),
GoRoute(
path: '/email/inbox/:id',
pageBuilder: (BuildContext context, GoRouterState state) {
return PageTransition.slideFromLeft(
myChildWidget: Layout(
context: context,
state: state,
child: const EmailDetailsPage(),
),
state: state,
);
},
),
GoRoute(
path: '/menu',
pageBuilder: (BuildContext context, GoRouterState state) {
return PageTransition.slideFromRight(
myChildWidget: Layout(
context: context,
state: state,
child: const MenuPage(),
),
state: state,
);
},
)
],
);
PageTransition is just a custom transition Widget I build.
So, in this case, if I do GoRouter.of(context).go('/inbox') it will play the slideFromRight transition, if I do GoRouter.of(context).go('/email/inbox/:id') it will play the slideFromLeft and I can't change that. I would like for this to be dynamic and choose what animation it is going to play.
go_router provides CustomTransitionPage for transition animations.
Code:
GoRoute(
path: 'details',
pageBuilder: (context, state) {
return CustomTransitionPage(
key: state.pageKey,
child: DetailsScreen(),
transitionsBuilder: (context, animation, secondaryAnimation, child) {
// Change the opacity of the screen using a Curve based on the the animation's
// value
return FadeTransition(
opacity:
CurveTween(curve: Curves.easeInOutCirc).animate(animation),
child: child,
);
},
);
},
),
Reference: https://github.com/flutter/packages/blob/main/packages/go_router/example/lib/transition_animations.dart

Flutter PageTransitionSwitcher is not working

I want to add an animation when transitioning from user's profile page to the previous page. so I used PageTransitionSwitcher as already I'm using animations package for another purpose in the app.This is how I implemented it inside the back button of the page.When I click on back button it is not working.
onPress: () => {
PageTransitionSwitcher(
transitionBuilder: (child, animation, secondaryAnimation) =>
SharedAxisTransition(animation: animation, secondaryAnimation: secondaryAnimation,
transitionType: SharedAxisTransitionType.horizontal),
child: NewMainTabs(),
)
},
you can use this function to build the route.
import 'package:animations/animations.dart';
import 'package:flutter/material.dart';
Route buildSharedZAxisTransitionPageRoute(Widget Function(BuildContext) builder,{RouteSettings? settings}) {
return PageRouteBuilder(
settings: settings,
pageBuilder: (context, animation, secondaryAnimation) => builder(context),
transitionsBuilder: (context, animation, secondaryAnimation, child) {
return SharedAxisTransition(
fillColor: Theme.of(context).cardColor,
animation: animation,
secondaryAnimation: secondaryAnimation,
transitionType: SharedAxisTransitionType.scaled,
child: child,
);
});
}
Then you can call upper function to create your route and push it into navigator or just rebuild with another widget
Widget build(BuildContext context) {
return PageTransitionSwitcher(
transitionBuilder: (
Widget child,
Animation<double> primaryAnimation,
Animation<double> secondaryAnimation,
) {
return FadeThroughTransition(
child: child,
animation: primaryAnimation,
secondaryAnimation: secondaryAnimation,
);
},
child: MyWidget(),
);
or
Navigator.of(context, rootNavigator: true).push(
buildSharedZAxisTransitionPageRoute(
(_) => const MyWidget())