Reputation: 760
The default flutter animation to transit a new page into the focus is to slide it up from the bottom. How do i change this behaviors and slide the new page in from the right or left instead?
Navigator.push(
context,
new PageRouteBuilder(
pageBuilder: (BuildContext context, _, __) {
return new SearchView();
}
)
);
Upvotes: 19
Views: 26159
Reputation: 179
A modified version of Matteo Antolini's answer:
import 'package:flutter/material.dart';
class ScreenNavigator {
final BuildContext cx;
ScreenNavigator({
required this.cx,
});
navigate(Widget page, Tween<Offset> tween) {
Navigator.push(
cx,
PageRouteBuilder(
pageBuilder: (context, animation, secondaryAnimation) {
return page;
},
transitionDuration: Durations.long1,
transitionsBuilder: (context, animation, secondaryAnimation, child) {
// create CurveTween
const Curve curve = Curves.ease;
final CurveTween curveTween = CurveTween(curve: curve);
// chain Tween with CurveTween
final Animatable<Offset> chainedTween = tween.chain(curveTween);
final Animation<Offset> offsetAnimation =
animation.drive(chainedTween);
return SlideTransition(position: offsetAnimation, child: child);
},
),
);
}
}
class NavigatorTweens {
static Tween<Offset> bottomToTop() {
const Offset begin = Offset(0.0, 1.0);
const Offset end = Offset(0.0, 0.0);
return Tween(begin: begin, end: end);
}
static Tween<Offset> topToBottom() {
const Offset begin = Offset(0.0, -1.0);
const Offset end = Offset(0.0, 0.0);
return Tween(begin: begin, end: end);
}
static Tween<Offset> leftToRight() {
const Offset begin = Offset(-1.0, 0.0);
const Offset end = Offset(0.0, 0.0);
return Tween(begin: begin, end: end);
}
static Tween<Offset> rightToLeft() {
const Offset begin = Offset(1.0, 0.0);
const Offset end = Offset(0.0, 0.0);
return Tween(begin: begin, end: end);
}
}
you can copy+paste it in a file and use it across your app like:
onTap: () {
ScreenNavigator(cx: context)
.navigate(Page(),NavigatorTweens.leftToRight());
},
to have better understanding of page sliding transition, read the official document
Upvotes: 0
Reputation: 624
import 'package:flutter/material.dart';
void main() {
runApp(
const MaterialApp(
home: Page1(),
),
);
}
class Page1 extends StatelessWidget {
const Page1({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
body: Center(
child: ElevatedButton(
onPressed: () {
Navigator.of(context).push(_createRoute());
},
child: const Text('Open Page Two'),
),
),
);
}
}
Route _createRoute() {
return PageRouteBuilder(
pageBuilder: (context, animation, secondaryAnimation) => const Page2(),
transitionsBuilder: (context, animation, secondaryAnimation, child) {
const begin = Offset(1.0, 0.0);
const end = Offset.zero;
const curve = Curves.ease;
var tween = Tween(begin: begin, end: end).chain(CurveTween(curve: curve));
return SlideTransition(
position: animation.drive(tween),
child: child,
);
},
);
}
class Page2 extends StatelessWidget {
const Page2({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
body: const Center(
child: Text('Hi, This is Page Two! (slided-In from Right)'),
),
);
}
}
This creates a two page route with transitions, see here for more info
Upvotes: 0
Reputation: 3068
You can create a function with your desirable animation
Route createRoute(Widget page) {
return PageRouteBuilder(
pageBuilder: (context, animation, secondaryAnimation) => page,
transitionsBuilder: (context, animation, secondaryAnimation, child) {
const begin = Offset(1.0, 0.0);
const end = Offset.zero;
const curve = Curves.ease;
var tween = Tween(begin: begin, end: end).chain(CurveTween(curve: curve));
return SlideTransition(
position: animation.drive(tween),
child: child,
);
},
);
}
And call it each time you push to a new screen
Navigator.of(context).push(createRoute(SearchView()))
If you want to change the direction you need to change the offset of begin
If you want to change the effect you need to change SlideTransition
Upvotes: 15
Reputation: 42383
Check out the CupertinoPageRoute:
A modal route that replaces the entire screen with an iOS transition.
The page slides in from the right and exits in reverse. The page also shifts to the left in parallax when another page enters to cover it.
The page slides in from the bottom and exits in reverse with no parallax effect for fullscreen dialogs.
There's a demo of it in the flutter gallery example app:
Navigator.of(context, rootNavigator: true).push(
new CupertinoPageRoute<bool>(
fullscreenDialog: true,
builder: (BuildContext context) => new Tab3Dialog(),
),
);
Upvotes: 25