Animation을 이용하여 page 전환하는 방법에 대해서 알아보겠습니다.
PageRouteBuilder 를 사용할 것이고, PageRouteBuilder 는 2가지 callback을 가지고 있습니다.
- pageBuilder : route의 content를 build
- transitionsBuilder : route의 transition을 build. transitionsBuilder의 child parameter는 pageBuilder에서 온 widget 입니다.
home route인 'Page1' 과 두번째 route인 'Page2'를 생성하였습니다.
import 'package:flutter/material.dart';
void main() {
runApp(
MaterialApp(
home: Page1(),
),
);
}
class Page1 extends StatelessWidget {
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
body: Center(
child: ElevatedButton(
onPressed: () {
Navigator.of(context).push(_createRoute());
},
child: Text('Go!'),
),
),
);
}
}
Route _createRoute() {
return PageRouteBuilder(
pageBuilder: (context, animation, secondaryAnimation) => Page2(),
transitionsBuilder: (context, animation, secondaryAnimation, child) {
return child;
},
);
}
class Page2 extends StatelessWidget {
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
body: Center(
child: Text('Page 2'),
),
);
}
}
아래쪽에서 새로운 페이지가 생성되도록 animation을 만들기 위해서 begin, end 를 각각 Offset(0.0, 1), Offset.zero로 설정합니다.
transitionsBuilder: (context, animation, secondaryAnimation, child) {
var begin = Offset(0.0, 1.0);
var end = Offset.zero;
var tween = Tween(begin: begin, end: end);
var offsetAnimation = animation.drive(tween);
return child;
},
Animation의 값이 변화하면 rebuild하는 AnimatedWidget 을 사용합니다. 여기서는 SlideTransition 을 사용했습니다.
transitionsBuilder: (context, animation, secondaryAnimation, child) {
var begin = Offset(0.0, 1.0);
var end = Offset.zero;
var tween = Tween(begin: begin, end: end);
var offsetAnimation = animation.drive(tween);
return SlideTransition(
position: offsetAnimation,
child: child,
);
},
Flutter는 시간에 따른 animation의 속도를 조정하는 easing curve를 제공합니다. Curves class에는 미리 정의된 curve들이 있습니다.
var curve = Curves.ease;
var curveTween = CurveTween(curve: curve);
위에서 정의한 2개의 tween을 chain() 을 이용하여 결합합니다.
그리고 결합하여 만든 새로운 tween을 animation.drive() 에 넣어줍니다.
animation이 동작할 때, 값은 다음의 순서로 계산됩니다.
transitionsBuilder: (context, animation, secondaryAnimation, child) {
var begin = Offset(0.0, 1.0);
var end = Offset.zero;
var curve = Curves.ease;
var curveTween = CurveTween(curve: curve);
var tween = Tween(begin: begin, end: end).chain(curveTween);
var offsetAnimation = animation.drive(tween);
return SlideTransition(
position: offsetAnimation,
child: child,
);
},