i have the code below and what i would like to achieve is to have an animation transition like 'pop' when calling 'push'. the code that i have just slides the new page from the direction that i specify. i would like to have the old screen be the one that is moving instead.
import 'package:flutter/material.dart';
class CustomPageRoute extends PageRouteBuilder {
final Widget child;
final AxisDirection direction;
CustomPageRoute({
required this.child,
required this.direction,
}) : super(
transitionDuration: const Duration(milliseconds: 200),
reverseTransitionDuration: const Duration(milliseconds: 200),
pageBuilder: (context, animation, secondaryAnimation) => child,
);
#override
Widget buildTransitions(BuildContext context, Animation<double> animation,
Animation<double> secondaryAnimation, Widget child) =>
SlideTransition(
position: Tween<Offset>(begin: getBeginOffset(), end: Offset.zero)
.animate(animation),
child: child,
);
Offset getBeginOffset() {
switch (direction) {
case AxisDirection.up:
return const Offset(0, 1);
case AxisDirection.down:
return const Offset(0, -1);
case AxisDirection.right:
return const Offset(-1, 0);
case AxisDirection.left:
return const Offset(1, 0);
}
}
}
You can use pageRouteBuilder with zero duration
Navigator.pushReplacement(
context,
PageRouteBuilder(
pageBuilder: (context, _, __) => NewPage(),
transitionDuration: Duration.zero,
reverseTransitionDuration: Duration.zero,
),
);
Edit
Navigator.push(
context,
PageRouteBuilder(
pageBuilder: (context, _, __) => Page2(),
transitionsBuilder: (context, anim, a2, child) => FadeTransition(opacity: anim, child: child),
transitionDuration: Duration(milliseconds: 2000),
),
);
for anyone looking to achieve the same thing, it can be achieved by using popUntil
Related
I want to get this type of transition animation .
But when I use
class CustomPageTransitionBuilder extends PageTransitionsBuilder {
#override
Widget buildTransitions<T>(
PageRoute<T> route,
BuildContext context,
Animation<double> animation,
Animation<double> secondaryAnimation,
Widget child,
) {
double begin = 0;
double end = 1.0;
var curve = Curves.easeOut;
final tween = Tween(
begin: begin,
end: end,
).chain(CurveTween(
curve: curve,
));
final scaleAnimation = animation.drive(tween);
if (route.settings.name == '/') {
return child;
}
return ScaleTransition(
scale: scaleAnimation,
child: child,
);
}
}
and in Main.dart:
MaterialApp(
theme: ThemeData(
pageTreansitionsTheme: PageTransitionsTheme( builders: {
TargetPlatform.android: CustomPageTransitionBuilder()
}
)
)
I get this type of animation:
Its somehow okay while navigating to the page . But when I go back I see weird animation effect.
Try this Code for Navigation
Navigator.push(
context,
PageRouteBuilder(
transitionDuration: const Duration(seconds: 1),
transitionsBuilder: (BuildContext context,
Animation<double> animation,
Animation<double> secAnimation,
Widget child) {
animation = CurvedAnimation(
parent: animation, curve: Curves.elasticOut);
return ScaleTransition(
scale: animation,
alignment: Alignment.center,
child: child);
},
pageBuilder: (BuildContext context,
Animation<double> animation,
Animation<double> secAnimation) {
return SecondScreen();
}));
You can do it using Hero animation.
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())
final builder = OpenUpwardsPageTransitionsBuilder();
Navigator.push(
context,
PageRouteBuilder(
pageBuilder: (_, __, ___) => Page2(),
transitionsBuilder: builder, // error
),
);
What I understand is, I can only setup PageTransitionsBuilder inside a Theme, is there any way to use it inside Navigator?
The most simple solution is a custom PageRouteBuilder:
class MyPageRouteBuilder<T> extends PageRouteBuilder<T> {
final PageTransitionsBuilder pageTransitionsBuilder;
MyPageRouteBuilder({
#required RoutePageBuilder pageBuilder,
#required this.pageTransitionsBuilder,
}) : assert(pageTransitionsBuilder != null), super(pageBuilder: pageBuilder);
#override
Widget buildTransitions(BuildContext context, Animation<double> animation, Animation<double> secondaryAnimation, Widget child) {
return pageTransitionsBuilder.buildTransitions(this, context, animation, secondaryAnimation, child);
}
}
Here only pageBuilder is passed to super() but you can add any named parameter that PageRouteBuilder accepts (like transitionDuration for example)
Now, you can use it with:
Navigator.of(context).push(
MyPageRouteBuilder(
pageBuilder: (ctx, a1, a2) => Page2(),
pageTransitionsBuilder: OpenUpwardsPageTransitionsBuilder(),
)
);
Navigator.push(
context,
PageRouteBuilder(
pageBuilder: (ctx, a1, a2) => Screen2(),
transitionsBuilder: (ctx, anim, a2, child) => FadeTransition(opacity: anim, child: child),
transitionDuration: Duration(milliseconds: 3000),
),
);
You can vary milliseconds time, as per your need in-app.
How do I add a duration to the CupertinoPageRoute? Currently it slides too quick and the effect is not very good.
Navigator.push(
context,
CupertinoPageRoute<Null>(
builder: (context) => View(),
),
);
My solution was not via CupertinoPageRoute, but maybe it can help.
Create a Route that you can customise:
Route yourCustomRoute() {
return PageRouteBuilder(
pageBuilder: (context, animation, secondaryAnimation) => YourView(),
transitionsBuilder: (context, animation, secondaryAnimation, child) {
var begin = Offset(-0.1, -0.1); //start position from top and left corner f.e.
var end = Offset.zero;
var curve = Curves.ease;
var tween =
Tween(begin: begin, end: end).chain(CurveTween(curve: curve));
return SlideTransition(
position: animation.drive(tween),
child: child,
);
},
transitionDuration: Duration(seconds: 10) //any duration you want
);
}
Add your route to Navigator:
Navigator.of(context).push(yourCustomRoute());
Read about routing between two pages here: https://flutter.dev/docs/cookbook/animation/page-route-animation
in our application we implementing custom route navigation and i want to set transition for that, for example, this is our custom route which that work fine without any problem
Navigator(
key: navigatorKey,
initialRoute: Page.screenDashboard.route,
onGenerateRoute: (settings) {
final pageName = settings.name;
final page = _fragments.keys.firstWhere(
(element) => describeEnum(element) == pageName);
return MaterialPageRoute(
builder: (context) => FadeAndSlideRightTransition(page: _fragments[page]));
},
),
in that how can i set transition for MaterialPageRoute?
for example:
class SlideRightRoute extends PageRouteBuilder {
final Widget page;
SlideRightRoute({this.page})
: super(
pageBuilder: (
BuildContext context,
Animation<double> animation,
Animation<double> secondaryAnimation,
) =>
page,
transitionsBuilder: (
BuildContext context,
Animation<double> animation,
Animation<double> secondaryAnimation,
Widget child,
) =>
SlideTransition(
position: Tween<Offset>(
begin: const Offset(-1, 0),
end: Offset.zero,
).animate(animation),
child: child,
),
);
}
this test doesn't work and i get error:
return MaterialPageRoute(builder: (context) => SlideRightRoute (page: _fragments[page]));
error
error: The return type 'SlideRightRoute ' isn't a 'Widget', as required by the closure's context. (return_of_invalid_type_from_closure at [fluttersamples] lib\screens.dart:62)
using
return SlideRightRoute(page: _fragments[page]);
instead of
return MaterialPageRoute(builder: (context) => _fragments[page]);
solved my issue